nanoant20 Temat założony przez niniejszego użytkownika |
call destructor > call constructor, code review, comments » 2024-03-13 10:20:20 Proszę o sprawdzenie kodu, dostaje dziwną liczbę wywołań destruktorów. Następna rzecz to czy w "default constructor" powinienem dodać vector<Student> students;. Poniżej Listing z moim kodem.: #include <iostream> #include <vector> #include <string> #include <sstream> #include <limits> #include <iterator> #include <algorithm>
using namespace std;
class Student { private: string name; string lastname; string input; int age { 100 }; double value { 0.0 }; vector < double > grades { 3.14, 9.80, 2025, 3195 }; vector < Student > students; public: Student() { cout << "parameterless default constructor" << "\n"; this->name = "NoName"; this->lastname = "Anonimus"; this->age = 20; } Student( const string & name_, const string & lastname_, int age_, vector < double > grades_ ) : name( name_ ) , lastname( lastname_ ) , age( age_ ) , grades( move( grades_ ) ) { cout << "default constructor" << "\n"; } void display() const { cout << name << " " << lastname << " " << age << endl; cout << "Gradess : "; copy( grades.begin(), grades.end(), ostream_iterator < double >( cout, " " ) ); cout << "\n"; } void displayAllStudents() const { for( const auto & student: students ) { student.display(); } } void inputUserData() { Student newStudent; cout << "Enter name: "; std::getline( cin, newStudent.name ); cout << "Enter lastname: "; std::getline( cin, newStudent.lastname ); cout << "Enter age: "; cin >> newStudent.age; clear_input_stream(); change( newStudent.grades ); students.push_back( newStudent ); } std::vector < double > change( vector < double > & grades ) { grades.clear(); std::cout << "Enter double values separated by spaces (np. 10.20 3.14 25.6): \n"; std::getline( std::cin, input ); std::istringstream iss( input ); while( iss >> value ) { grades.push_back( value ); } return grades; } void clear_input_stream() { std::cin.clear(); std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' ); } ~Student() { cout << "~destruktor" << "\n"; } }; auto main()->int { Student newStudent; int how_many { 0 }; cout << "How many students do you want to add? : "; cin >> how_many; newStudent.clear_input_stream(); while( how_many ) { newStudent.inputUserData(); --how_many; } cout << "\n"; newStudent.displayAllStudents(); cout << "\n"; string antrakt = ""s; std::cin >> noskipws >> antrakt; return( antrakt.empty() ) ?( EXIT_SUCCESS ) :( EXIT_SUCCESS ); }
|
|
DejaVu |
» 2024-03-13 10:28:35 Szczerze mówiąc code review nie ma sensu dla tak małych programów. Obecnie jesteś na etapie nauki, więc ani nie trzymasz standardów, ani nie używasz listy inicjalizacyjnej konstruktora, kopiujesz vector w konstruktorze, tworzysz destruktor, który nie dostarcza żadnej realnej wartości poza edukacyjnym walorem oraz jakąś dziwną składnię main-a zrobiłeś, która nawet nie wiem czy się skompiluje. |
|
nanoant20 Temat założony przez niniejszego użytkownika |
» 2024-03-13 10:58:14 Szczerze mówiąc code review nie ma sensu dla tak małych programów. może faktycznie tytuł był mylący "code review, comments" i zminiłem go na "call destructor > call constructor, code review, comments" Destruktor niczego nie robi, dane zostaną usunięte przez wektor, komunikat w nim jest dla mnie. Nawet nie jestem pewny czy w ogóle jest tutaj ten destruktor potrzebny. I dlatego poprosiłem o sprawdzenie. dalej nie wiem dlaczego jest więcej wywołań destruktora od wywołań konstruktoraprzy wprowadzeniu np. 3 żaków, wywoływane są 4 konstruktory i 8 destruktorów jakąś dziwną składnię main-a zrobiłeś, która nawet nie wiem czy się skompiluje. Dostarczyłem minimalny i kompletny przykład. Kompiluje sie. -std=c++20 Chodzi o ten kawałek cout << "\n"; string antrakt = ""s; std::cin >> noskipws >> antrakt; return( antrakt.empty() ) ?( EXIT_SUCCESS ) :( EXIT_SUCCESS );
tak robię w windows "window freezing" zamiast cin.get() czy pause(); Oczywiście mogłem po ludzku napisać return(0); nie używasz listy inicjalizacyjnej konstruktora, nie miałem na nią żadnego pomysłu kopiujesz vector w konstruktorze, nie, grades(move(grades_)) przenosi zasoby z jednego obiektu do drugiego bez zbędnego kopiowania, tzw referencje do r-wartości (ang. r-value references), tak przynajmniej zrozumiałem z artykułu o "semantyce przeniesienia". |
|
pekfos |
» 2024-03-13 18:12:13 dalej nie wiem dlaczego jest więcej wywołań destruktora od wywołań konstruktora Bo nie liczysz wywołań konstruktora kopiującego / przenoszącego. Jest powód dla którego te składnie istnieją, ale używanie ich bez powodu raczej pokazuje że nie wiesz co robisz. |
|
nanoant20 Temat założony przez niniejszego użytkownika |
» 2024-03-13 19:41:44 Jest powód dla którego te składnie istnieją, ale używanie ich bez powodu raczej pokazuje że nie wiesz co robisz. "auto main() -> int" zmaist "int main()" obie formy są równoważne, z tym że "auto main() -> int" stosuje się częściej w w szablonach funkcji. int how_many{0} to lista inicjalizacyjna int how_many = 0; klasyczna inicjalizacja "int how_many{0}" zamiast "int how_many = 0;" tak jak wyżej obie formy inicjalizacji działają podobnie, wybór zależy od preferencji Napisałem wcześniej że "Dostarczyłem minimalny i kompletny przykład." Nie użyłem szablonu, żeby nie zaciemniać kodu. Jeżeli chodzi o "konstruktora kopiującego", już sobie go dopisałem, zapomniałem o nim. Dziękuję |
|
pekfos |
» 2024-03-13 20:38:56 main() jest tu jedyną funkcją w tej formie, więc w oryginalnym kodzie main było szablonem? Minimalny przykład nie miałby tego całego wczytywania danych które nie ma związku z tym co chcesz pokazać i tylko utrudnia uruchomienie tego kodu. wybór zależy od preferencji Czyli po prostu preferujesz dłuższy zapis wymagający machania shiftem? Chyba nie piszesz za dużo kodu. |
|
nanoant20 Temat założony przez niniejszego użytkownika |
» 2024-03-13 21:28:00 main() jest tu jedyną funkcją w tej formie, więc w oryginalnym kodzie main było szablonem? Minimalny przykład nie miałby tego całego wczytywania danych które nie ma związku z tym co chcesz pokazać i tylko utrudnia uruchomienie tego kodu. to w takim razie w jakiej formie miałbym dostarczyć kod, (rozumiem, że w tym wypadku wystarczyła by sama klasa) "tylko utrudnia uruchomienie tego kodu." nie rozumiem, kod się kompiluje bez żadnych worning'ów |
|
pekfos |
» 2024-03-13 22:09:26 Kod nie powinien wymagać wprowadzania żadnych danych, zwłaszcza gdy ich nie określisz. Dla jakiej liczby studentów obserwujesz tą "dziwną liczbę wywołań destruktorów"? To ma znaczenie? A skąd ja mam wiedzieć? Wiem tylko że ta liczba jest "dziwna". Okroiłem ten kod do bardziej minimalnej formy i albo reprodukuje problem, albo źle zgadłem niewiadome w twoim pytaniu. #include <iostream> #include <vector> #include <string> #include <sstream> #include <limits> #include <iterator> #include <algorithm>
using namespace std;
class Student { private: string name; string lastname; string input; int age { 100 }; double value { 0.0 }; vector < double > grades { 3.14, 9.80, 2025, 3195 }; vector < Student > students; public: Student() { cout << "parameterless default constructor" << "\n"; this->name = "NoName"; this->lastname = "Anonimus"; this->age = 20; } Student( const string & n, const string & l, int a, vector < double > grades_ ) : name( n ) , lastname( l ) , age( a ) , grades( move( grades_ ) ) { cout << "default constructor" << "\n"; } void display() const { cout << name << " " << lastname << " " << age << endl; cout << "Gradess : "; copy( grades.begin(), grades.end(), ostream_iterator < double >( cout, " " ) ); cout << "\n"; } void displayAllStudents() const { for( const auto & student: students ) { student.display(); } } void inputUserData() { Student newStudent; clear_input_stream(); change( newStudent.grades ); students.push_back( newStudent ); } std::vector < double > change( vector < double > & grades ) { grades.clear(); std::istringstream iss( input ); while( iss >> value ) { grades.push_back( value ); } return grades; } void clear_input_stream() { } ~Student() { cout << "~destruktor" << "\n"; } }; auto main()->int { Student newStudent; int how_many { 5 }; newStudent.clear_input_stream(); while( how_many ) { newStudent.inputUserData(); --how_many; } } |
|
« 1 » 2 |