Lich555 Temat założony przez niniejszego użytkownika |
Wywołanie konstruktora » 2016-12-11 22:46:06 Witam. Dam przykład: class kolo { float k; int a; char c; kolo( float, int, char ) }; kolo::kolo( float p, int o, char i ) : k( p ) , a( o ) , c( i ) { }
int main() { kolo obiekt1( 2.5, 8, 'c' ); kolo obiekt1 = kolo( 2.5, 8, 'c' ); return 0; }
Czy pomiędzy tymi dwoma, różnymi z wyglądu, wywołaniami tego samego konstruktora jest jakaś różnica? |
|
michal11 |
» 2016-12-11 23:13:59 Na moje oko teoretycznie, powinien być wywołany konstruktor z parametrem a później kopiujący/przenoszący, ale najpewniej kompilator to odpowiednio zoptymalizuje żeby było tylko jedno wywołanie (co zresztą miało miejsce w moich małych testach). |
|
mokrowski |
» 2016-12-11 23:28:24 Dla kodu tylko nieznacznie poprawionego... #include <iostream>
class kolo { public: float k; int a; char c; kolo(); kolo( float, int, char ); kolo( const kolo & src ); kolo & operator =( const kolo & src ); }; kolo::kolo() { std::cout << "konstruktor domyślny" << std::endl; } kolo::kolo( float p, int o, char i ) : k( p ) , a( o ) , c( i ) { std::cout << "Wołanie konstruktora argumentami" << std::endl; } kolo::kolo( const kolo & src ) : k( src.k ) , a( src.a ) , c( src.c ) { std::cout << "Wołanie konstruktora kopiującego" << std::endl; } kolo & kolo::operator =( const kolo & src ) { std::cout << "Operator przypisania" << std::endl; return * this; }
int main() { kolo obiekt1( 2.5, 8, 'c' ); kolo obiekt2 = kolo( 2.5, 8, 'c' ); return 0; }
.. drugie wywołanie (to ze słowem "tutaj") będzie kończyło się optymalizacją http://en.cppreference.com/w/cpp/language/copy_elision Jeśli dla g++ lub clang++ chcesz wyłączyć optymalizację, dodaj przełącznik: dla: clang++ -o kon kon.cpp wynik: Wołanie konstruktora argumentami Wołanie konstruktora argumentami dla: clang++ -fno-elide-constructors -o kon kon.cpp wynik: Wołanie konstruktora argumentami Wołanie konstruktora argumentami Wołanie konstruktora kopiującego W C++11 ta optymalizacja była opcjonalna (każdy wytwórca robił jak chciał i np. kompilator VS w trybie debug nie robił optymalizacji) a od C++14 jest ona obowiązkowa. |
|
Lich555 Temat założony przez niniejszego użytkownika |
» 2016-12-12 09:09:18 Trochę olałem sprawę, ale nie przyłożyłem się do tego kodu, gdyż tak cz. wg mnie była nieistotna. Dla mnie istotne było tylko i wyłącznie różnice w wywołaniu. 1. klasa obiekt( argumenty );
2. klasa obiekt = konstruktor( argumenty );
|
|
czaffik |
» 2016-12-14 21:10:27 1. klasa obiekt( argumenty );
Ten konstruktor po prostu tworzy obiekt i do pól przypisuje podane wartości; 2. klasa obiekt = konstruktor( argumenty );
Ten natomiast tworzy najpierw anonimowy obiekt klasy, przypisuje do pól podane wartości a potem całość kopiuje do obiektu występującego po lewej stronie. Jeżeli chodzi o efekt końcowy to bez różnicy który zapis zastosujesz, wydaje mi się że drugi sposób będzie nieco wolniejszy aczkolwiek będzie to zapewne tak niewielka różnica że nikt nie zauważy. No i przede wszystkim w podanym przez ciebie przykładzie wywołanie któregokolwiek konstruktora nie zadziała, bo oba masz private :P Zapomniałbym, drugiego konstruktora nawet nie napisałeś w swoim kodzie, został utworzony automatycznie przez kompilator, efekt końcowy akurat tutaj będzie ten sam, ale mogą być przypadki kiedy nie będzie ten sam, zwłaszcza gdy będziesz miał wskaźniki. |
|
carlosmay |
» 2016-12-14 21:33:47 Jeżeli chodzi o efekt końcowy to bez różnicy który zapis zastosujesz, wydaje mi się że drugi sposób będzie nieco wolniejszy aczkolwiek będzie to zapewne tak niewielka różnica że nikt nie zauważy. |
Pewnie optymalizacje pominą konstruktor kopiujący lub operator przypisania i w obu przypadkach wywołany zostanie tylko konstruktor z parametrem. |
|
« 1 » |