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

Konstruktor kopiujący

Ostatnio zmodyfikowano 2016-12-08 23:40
Autor Wiadomość
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:
C/C++
kalibracja::kalibracja( kalibracja & wzorzec )
{
    a = wzorzec.a;
    b = wzorzec.b;
   
    strncpy( nazwa, "-- To ja, konstruktor kopiujacy!!!--", sizeof( nazwa ) );
}
Stworzyłem w main takie obiekty
C/C++
kalibracja kobalt( 1.07, 2.4, "ORYGINALNA KOBALTOWA" );
//...
kalibracja europ( kobalt );
Mam też tablicę znaków i zapisuję w niej osobną metodą:
C/C++
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:
C/C++
kalibracja fun_druga()
{
    kalibracja wewn( 2, 1, "WEWNETRZNA" );
    cout << "W funkcji fun_druga definiuje kalibracej i ma ona opis: " << wewn.opis() << endl; //tutaj wyświetli "WPISANE" czyli wpisane do obiektu wartosci zwykłym konstruktorem
    return wewn; //zwracany obiekt to obiekt klasy (typu) kalibracja
}
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ść.
P-154636
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
C/C++
kalibracja( const kalibracja & );
P-154637
mateczek
» 2016-12-07 22:56:51
nie ma potrzeby tworzenia kopii obiektu więc kompilator nie tworzy
P-154638
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?
P-154671
Monika90
» 2016-12-08 17:46:18
W takiej sytuacji
C/C++
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
C/C++
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.
P-154672
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)?
P-154677
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
C/C++
void f( int & n ) { }

int main()
{
    const int n = 7;
    f( n ); //to się nie skompiluje
    f( 2 + 2 ); //to też nie, trzeba dopisać const w deklaracji parametru funkcji f
}
P-154678
« 1 »
  Strona 1 z 1