Lich555 Temat założony przez niniejszego użytkownika |
Konstruktor kopiujący » 2016-12-07 22:41:28 Witam. Mam 2 konstruktory i 1 z nich jest kopiujący. Wygląda on następująco: kalibracja::kalibracja( kalibracja & wzorzec ) { a = wzorzec.a; b = wzorzec.b; strncpy( nazwa, "-- To ja, konstruktor kopiujacy!!!--", sizeof( nazwa ) ); }
Stworzyłem w main takie obiekty kalibracja kobalt( 1.07, 2.4, "ORYGINALNA KOBALTOWA" );
kalibracja europ( kobalt );
Mam też tablicę znaków i zapisuję w niej osobną metodą: const char * opis() { return( nazwa ); }
Gdy wywołam: kobalt.opis() Na ekranie pojawia mi się tak jak oczekiwałem to co jest w tablicy znaków, czyli "ORYGINALNA KOBALTOWA" Gdy wywołam: europ.opis() Na ekranie pojawia mi się tak jak oczekiwałem to co jest w tablicy znaków, czyli "-- To ja, konstruktor kopiujacy!!!--" Mam również funkcję zwracającą obiekt typu mojej klasy kalibracja: kalibracja fun_druga() { kalibracja wewn( 2, 1, "WEWNETRZNA" ); cout << "W funkcji fun_druga definiuje kalibracej i ma ona opis: " << wewn.opis() << endl; return wewn; }
Gdy ją wywołam w main taki sposób: fun_druga().opis() To na ekranie również widzę "WPISANE". Czy przy wywołaniu jej w main nie powinienem ujrzeć tego, co wypisuje konstruktor kopiujący, czyli "-- To ja, konstruktor kopiujacy!!!--"? Przecież przesyłam tak jakby wewn.opis(). Nie wysyłam danych wartości, lecz obiekt zwrócony przez wartość. |
|
Monika90 |
» 2016-12-07 22:56:34 Kompilator ma prawo nie wywołać konstruktora kopiującego, gdy nie jest on potrzebny. Jest to optymalizacja (named return value optimization), dzięki temu program działa szybciej i jest mniejszy. A poza tym, parametr konstruktora kopiującego powinien mieć atrybut const kalibracja( const kalibracja & );
|
|
mateczek |
» 2016-12-07 22:56:51 nie ma potrzeby tworzenia kopii obiektu więc kompilator nie tworzy |
|
Lich555 Temat założony przez niniejszego użytkownika |
» 2016-12-08 17:19:50 To jaka jest różnica, że przy wywołaniu z obiektem europ aktywuje się konstruktor kopiujący, a przy obiekcie zwracanym przez funkcję nie aktywuje się on? |
|
Monika90 |
» 2016-12-08 17:46:18 W takiej sytuacji int main() { kalibracja kobalt( 1.07, 2.4, "ORYGINALNA KOBALTOWA" ); kalibracja europ( kobalt ); }
masz dwa obiekty typu kalibracja, jeden jest utworzony jako kopia drugiego, ale potem istnieją jednocześnie i niezależnie od siebie. Nie ma innego sposobu uzyskania takiego stanu niż wywołanie konstruktora kopiującego. W tej sytuacji kalibracja fun() { kalibracja wewn( 2, 1, "WEWNETRZNA" ); return wewn; } int main() { kalibracja zewn = fun(); }
kompilator ma dwa drogi do wyboru: Sposób 1. Utworzyć obiekt wewn, w czasie powrotu z funkcji utworzyć obiekt zewn jako kopię obiektu wewn, zniszczyć obiekt wewn. Sposób 2. Utworzyć tylko jeden obiekt. Obiekt wewn i obiekt zewn to jest jeden i ten sam obiekt, po prostu ma dwie nazwy. Twój kompilator wybiera ten drugi sposób, bo to jest bardziej wydajny sposób. Unika zbędnych operacji tworzenia kopii i niszczenia obiektu. |
|
Lich555 Temat założony przez niniejszego użytkownika |
» 2016-12-08 21:18:23 Cofnę się do Twojej wcześniejszej wypowiedzi. Atrybut const jest w tym przypadku po to, by konstruktor kopiujący nie miał możliwości modyfikacji oryginału obiektu (tego, z którego kopiuje; source)? |
|
Monika90 |
» 2016-12-08 23:40:48 Dzięki temu że parametrem konstruktora jest referencja do const można kopiować stałe oraz obiekty tymczasowe. Tak samo jest ze zwykłymi funkcjami void f( int & n ) { }
int main() { const int n = 7; f( n ); f( 2 + 2 ); }
|
|
« 1 » |