Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

call destructor > call constructor, code review, comments

Ostatnio zmodyfikowano 2024-03-14 00:00
Autor Wiadomość
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.:
C/C++
#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"; // class destructor
   
}
}
;
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 );
}
P-180932
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.
P-180933
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ń konstruktora
przy 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
C/C++
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".






P-180934
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.

C/C++
auto main()->int
C/C++
int how_many { 0 };
Jest powód dla którego te składnie istnieją, ale używanie ich bez powodu raczej pokazuje że nie wiesz co robisz.
P-180935
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ę
P-180937
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.
P-180938
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
P-180939
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.
C/C++
#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;
       
//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"; // class destructor
   
}
}
;
auto main()->int
{
   
Student newStudent;
   
int how_many { 5 };
   
//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 );
}
P-180940
« 1 » 2
  Strona 1 z 2 Następna strona