08 konstruktor kopiujacy prez


Konstruktor kopiujÄ…cy
Bogdan Kreczmer
ZPCiR IIAiR PWr
pokój 307 budynek C3
bogdan.kreczmer@pwr.wroc.pl
Copyright ©2005 2010 Bogdan Kreczmer

Niniejszy dokument zawiera materiały do wykładu na temat programowania obiektowego. Jest on udostępniony pod
warunkiem wykorzystania wyłącznie do własnych prywatnych potrzeb i może on być kopiowany wyłącznie w całości, razem z
niniejszą stroną tytułową.
1
Klasy z polami wskaznikowymi
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
KopiaNapisu( ) { wNapis = NULL; }
<"
KopiaNapisu( ) { if ( wNapis) delete [ ] wNapis; }
const char "Wez( ) const { return wNapis; }
void Zmien( const char " wTekst )
}; //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
void KopiaNapisu::Zmien( const char " wTekst );
{
if ( wNapis ) delete [ ] wNapis;
if ( wTekst && ( wNapis = new char [strlen(wTekst)+1] ) ) strcpy( wNapis, wTekst );
}
Konstruktor kopiujÄ…cy
1
Klasy z polami wskaznikowymi
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
KopiaNapisu( ) { wNapis = NULL; }
<"
KopiaNapisu( ) { if ( wNapis) delete [ ] wNapis; }
const char "Wez( ) const { return wNapis; }
void Zmien( const char " wTekst )
}; //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
void KopiaNapisu::Zmien( const char " wTekst );
{
if ( wNapis ) delete [ ] wNapis;
if ( wTekst && ( wNapis = new char [strlen(wTekst)+1] ) ) strcpy( wNapis, wTekst );
}
Klasa KopiaNapisu ma dobrze zdefiniowany interfejs, który zabezpiecza ją przed przypadkowymi
zmianami pola wNapisoraz stowarzyszonego z niÄ… napisu.
Konstruktor kopiujÄ…cy
2
Klasy z polami wskaznikowymi
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
KopiaNapisu( ) { wNapis = NULL; }
<"
KopiaNapisu( ) { if ( wNapis) delete [ ] wNapis; }
const char "Wez( ) const { return wNapis; }
void Zmien( const char " wTekst );
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
void Wyswietl( KopiaNapisu Ob ) { cout <<  Wyswietl:  << Ob.Wez( ) << endl; }
int main( )
{
KopiaNapisu Ob;
Ob.Zmien(  Abu Ja far Mohammed ibn Mûsâ al-Khowârizmi );
cout <<  main 1:  << Ob.Wez( ) << endl;
Wyswietl(Ob);
cout <<  main 2:  << Ob.Wez( ) << endl;
}
Konstruktor kopiujÄ…cy
2
Klasy z polami wskaznikowymi
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
KopiaNapisu( ) { wNapis = NULL; }
<"
KopiaNapisu( ) { if ( wNapis) delete [ ] wNapis; }
const char "Wez( ) const { return wNapis; }
void Zmien( const char " wTekst );
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
void Wyswietl( KopiaNapisu Ob ) { cout <<  Wyswietl:  << Ob.Wez( ) << endl; }
int main( )
{
KopiaNapisu Ob;
Ob.Zmien(  Abu Ja far Mohammed ibn Mûsâ al-Khowârizmi );
cout <<  main 1:  << Ob.Wez( ) << endl;
Wyswietl(Ob);
Wynik działania:
cout <<  main 2:  << Ob.Wez( ) << endl;
main 1: Abu Ja far Mohammed ibn Musa al-Khowarizmi
}
Wyswietl: Abu Ja far Mohammed ibn Musa al-Khowarizmi
main 2:
Konstruktor kopiujÄ…cy
2
Klasy z polami wskaznikowymi
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
KopiaNapisu( ) { wNapis = NULL; }
<"
KopiaNapisu( ) { if ( wNapis) delete [ ] wNapis; }
const char "Wez( ) const { return wNapis; }
void Zmien( const char " wTekst );
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
void Wyswietl( KopiaNapisu Ob ) { cout <<  Wyswietl:  << Ob.Wez( ) << endl; }
int main( )
{
KopiaNapisu Ob;
Ob.Zmien(  Abu Ja far Mohammed ibn Mûsâ al-Khowârizmi );
cout <<  main 1:  << Ob.Wez( ) << endl;
Wyswietl(Ob);
Wynik działania:
cout <<  main 2:  << Ob.Wez( ) << endl;
main 1: Abu Ja far Mohammed ibn Musa al-Khowarizmi
}
Wyswietl: Abu Ja far Mohammed ibn Musa al-Khowarizmi
main 2:
Co stało się z napisem ???
Abu Ja far Mohammed ibn Mûsâ al-Khowârizmi  (780-850) arabski matematyk urodzony w Bagdadzie, jednym z jego najważniejszych dokonaÅ„
jest napisanie w 825 podręcznika pt.  Kitab al jabr w al-muqabala . Słowo algebra pochodzi z tytułu tego podręcznika (al jabr). Natomiast słowo
algorytm pochodzi od jego nazwiska. Uważał, że każdy problem matematyczny można rozwiązać w serii pojedynczych kroków.
Konstruktor kopiujÄ…cy
3
Przekazywanie obiektów przez wartość
Konstruktor kopiujÄ…cy
3
Przekazywanie obiektów przez wartość
Przekazaniu parametru wywołania funkcji/metody przez wartość towarzyszy utworzenie jego kopii na
poziomie tej funkcji/metody. Istnienie kopii kończy się wraz z zakończeniem działania funkcji/metody.
Konstruktor kopiujÄ…cy
4
Przekazywanie obiektów przez wartość (obiekt z polem wskaznikowym)
Konstruktor kopiujÄ…cy
4
Przekazywanie obiektów przez wartość (obiekt z polem wskaznikowym)
Przy tworzeniu kopii przepisana zostaje cała zawartość obiektu łącznie z zawartością pól wskazni-
kowych. Powoduje to, że dwa obiekty połączone są poprzez wskazniki z tymi samymi strukturami.
Konstruktor kopiujÄ…cy
5
Przekazywanie obiektów przez wartość (destrukcja cz.1)
Konstruktor kopiujÄ…cy
5
Przekazywanie obiektów przez wartość (destrukcja cz.1)
Destrukcja kopii obiektu pociÄ…ga za sobÄ… destrukcjÄ™ dynamicznych struktur z nim stowarzyszonych.
Usunięte zostają w ten sposób struktury, które pierwotnie należały do oryginału.
Konstruktor kopiujÄ…cy
6
Przekazywanie obiektów przez wartość (destrukcja cz.1)
Konstruktor kopiujÄ…cy
6
Przekazywanie obiektów przez wartość (destrukcja cz.1)
Destrukcja oryginału, po wcześniejszym niekontrolowanym usunięciu struktur stowarzyszonym z da-
nym obiektem, prowadzi do nieprzewidzianych skutków (zwykle jest to:segmentation fault:-).
Konstruktor kopiujÄ…cy
7
Przekazywanie obiektów przez wartość ( konstruktor kopiujący )
Konstruktor kopiujÄ…cy
7
Przekazywanie obiektów przez wartość ( konstruktor kopiujący )
Implementacja konstruktora kopiujÄ…cego pozwala na poprawne powielenie struktur stowarzyszonych
z oryginalnym obiektem. Tym samym zapewnia prawidłową pózniejszą destrukcję takiego obiektu.
Konstruktor kopiujÄ…cy
8
Przekazywanie obiektów przez referencję
Konstruktor kopiujÄ…cy
8
Przekazywanie obiektów przez referencję
Przekazywanie obiektu przez referencję pozwala uniknąć tworzenia kopii obiektu, która czasem
może być zbędna.
Konstruktor kopiujÄ…cy
9
Implementacja konstruktora kopiujÄ…cego
class KopiaNapisu { //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
KopiaNapisu( ) { wNapis = NULL; }
KopiaNapisu( const KopiaNapisu & Ob ) { wNapis = NULL; Zmien(Ob. wNapis); }
<"
KopiaNapisu( ) { if ( wNapis) delete [ ] wNapis; }
const char "Wez( ) const { return wNapis; }
void Zmien( const char " wTekst );
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
void Wyswietl( KopiaNapisu Ob ) { cout <<  Wyswietl:  << Ob.Wez( ) << endl; }
int main( )
{
KopiaNapisu Ob;
Ob.Zmien(  Abu Ja far Mohammed ibn Mûsâ al-Khowârizmi );
cout <<  main 1:  << Ob.Wez( ) << endl;
Wyswietl(Ob);
cout <<  main 2:  << Ob.Wez( ) << endl;
}
Konstruktor kopiujÄ…cy
9
Implementacja konstruktora kopiujÄ…cego
class KopiaNapisu { //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
KopiaNapisu( ) { wNapis = NULL; }
KopiaNapisu( const KopiaNapisu & Ob ) { wNapis = NULL; Zmien(Ob. wNapis); }
<"
KopiaNapisu( ) { if ( wNapis) delete [ ] wNapis; }
const char "Wez( ) const { return wNapis; }
void Zmien( const char " wTekst );
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
void Wyswietl( KopiaNapisu Ob ) { cout <<  Wyswietl:  << Ob.Wez( ) << endl; }
int main( )
{
KopiaNapisu Ob;
Ob.Zmien(  Abu Ja far Mohammed ibn Mûsâ al-Khowârizmi );
cout <<  main 1:  << Ob.Wez( ) << endl;
Wyswietl(Ob);
Wynik działania:
cout <<  main 2:  << Ob.Wez( ) << endl;
main 1: Abu Ja far Mohammed ibn Musa al-Khowarizmi
}
Wyswietl: Abu Ja far Mohammed ibn Musa al-Khowarizmi
main 2: Abu Ja far Mohammed ibn Musa al-Khowarizmi
Konstruktor kopiujÄ…cy
9
Implementacja konstruktora kopiujÄ…cego
class KopiaNapisu { //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
KopiaNapisu( ) { wNapis = NULL; }
KopiaNapisu( const KopiaNapisu & Ob ) { wNapis = NULL; Zmien(Ob. wNapis); }
<"
KopiaNapisu( ) { if ( wNapis) delete [ ] wNapis; }
const char "Wez( ) const { return wNapis; }
void Zmien( const char " wTekst );
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
void Wyswietl( KopiaNapisu Ob ) { cout <<  Wyswietl:  << Ob.Wez( ) << endl; }
int main( )
{
KopiaNapisu Ob;
Ob.Zmien(  Abu Ja far Mohammed ibn Mûsâ al-Khowârizmi );
cout <<  main 1:  << Ob.Wez( ) << endl;
Wyswietl(Ob);
Wynik działania:
cout <<  main 2:  << Ob.Wez( ) << endl;
main 1: Abu Ja far Mohammed ibn Musa al-Khowarizmi
}
Wyswietl: Abu Ja far Mohammed ibn Musa al-Khowarizmi
main 2: Abu Ja far Mohammed ibn Musa al-Khowarizmi
Implementacja konstruktora kopiującego zapewnia właściwe przekazywanie parametru i nie tylko.
Konstruktor kopiujÄ…cy
10
Implementacja konstruktora kopiujÄ…cego
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
KopiaNapisu( ) { wNapis = NULL; }
KopiaNapisu( const KopiaNapisu & Ob ) { wNapis = NULL; Zmien(Ob. wNapis); }
<"
KopiaNapisu( ) { if ( wNapis) delete [ ] wNapis; }
const char "Wez( ) const { return wNapis; }
void Zmien( const char " wTekst );
}; //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
int main( )
{
KopiaNapisu Ob1;
Ob1.Zmien( Hippasus z Metapontum );
{
KopiaNapisu Ob2;
Ob2 = Ob1;
cout <<  Ob1:  << Ob1.Wez( ) << endl;
cout <<  Ob2:  << Ob2.Wez( ) << endl;
}
cout <<  Ob1:  << Ob1.Wez( ) << endl;
}
Konstruktor kopiujÄ…cy
10
Implementacja konstruktora kopiujÄ…cego
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
KopiaNapisu( ) { wNapis = NULL; }
KopiaNapisu( const KopiaNapisu & Ob ) { wNapis = NULL; Zmien(Ob. wNapis); }
<"
KopiaNapisu( ) { if ( wNapis) delete [ ] wNapis; }
const char "Wez( ) const { return wNapis; }
void Zmien( const char " wTekst );
}; //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
int main( )
{
KopiaNapisu Ob1;
Ob1.Zmien( Hippasus z Metapontum );
{
KopiaNapisu Ob2;
Ob2 = Ob1;
cout <<  Ob1:  << Ob1.Wez( ) << endl;
Wynik działania:
cout <<  Ob2:  << Ob2.Wez( ) << endl;
} Ob1: Hippasus z Metapontum
Ob2: Hippasus z Metapontum
cout <<  Ob1:  << Ob1.Wez( ) << endl;
Ob1:
}
Konstruktor kopiujÄ…cy
10
Implementacja konstruktora kopiujÄ…cego
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
KopiaNapisu( ) { wNapis = NULL; }
KopiaNapisu( const KopiaNapisu & Ob ) { wNapis = NULL; Zmien(Ob. wNapis); }
<"
KopiaNapisu( ) { if ( wNapis) delete [ ] wNapis; }
const char "Wez( ) const { return wNapis; }
void Zmien( const char " wTekst );
}; //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
int main( )
{
KopiaNapisu Ob1;
Ob1.Zmien( Hippasus z Metapontum );
{
KopiaNapisu Ob2;
Ob2 = Ob1;
cout <<  Ob1:  << Ob1.Wez( ) << endl;
Wynik działania:
cout <<  Ob2:  << Ob2.Wez( ) << endl;
} Ob1: Hippasus z Metapontum
Ob2: Hippasus z Metapontum
cout <<  Ob1:  << Ob1.Wez( ) << endl;
Ob1:
}
Czemu ponownie brakuje tekstu?
Konstruktor kopiujÄ…cy
11
Implementacja operacji przypisania
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
. . .
KopiaNapisu & operator = ( const KopiaNapisu & Ob )
{ Zmien( Ob. wNapis ); return "this ; }
. . .
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
int main( )
{
KopiaNapisu Ob1;
Ob1.Zmien( Hippasus z Metapontum );
{
KopiaNapisu Ob2;
Ob2 = Ob1;
cout <<  Ob1:  << Ob1.Wez( ) << endl;
cout <<  Ob2:  << Ob2.Wez( ) << endl;
}
cout <<  Ob1:  << Ob1.Wez( ) << endl;
}
Konstruktor kopiujÄ…cy
11
Implementacja operacji przypisania
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
. . .
KopiaNapisu & operator = ( const KopiaNapisu & Ob )
{ Zmien( Ob. wNapis ); return "this ; }
. . .
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
int main( )
{
KopiaNapisu Ob1;
Ob1.Zmien( Hippasus z Metapontum );
{
KopiaNapisu Ob2;
Ob2 = Ob1;
cout <<  Ob1:  << Ob1.Wez( ) << endl;
Wynik działania:
cout <<  Ob2:  << Ob2.Wez( ) << endl;
} Ob1: Hippasus z Metapontum
Ob2: Hippasus z Metapontum
cout <<  Ob1:  << Ob1.Wez( ) << endl;
Ob1: Hippasus z Metapontum
}
Konstruktor kopiujÄ…cy
11
Implementacja operacji przypisania
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
. . .
KopiaNapisu & operator = ( const KopiaNapisu & Ob )
{ Zmien( Ob. wNapis ); return "this ; }
. . .
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
int main( )
{
KopiaNapisu Ob1;
Ob1.Zmien( Hippasus z Metapontum );
{
KopiaNapisu Ob2;
Ob2 = Ob1;
cout <<  Ob1:  << Ob1.Wez( ) << endl;
Wynik działania:
cout <<  Ob2:  << Ob2.Wez( ) << endl;
} Ob1: Hippasus z Metapontum
Ob2: Hippasus z Metapontum
cout <<  Ob1:  << Ob1.Wez( ) << endl;
Ob1: Hippasus z Metapontum
}
Stosowanie pól wskaznikowych wymaga prawie zawsze implementacji konstruktora kopiującego i
przeciążenia operatora przypisania.
Konstruktor kopiujÄ…cy
12
Konstruktor kopiujÄ…cy (raz jeszcze)
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
. . .
KopiaNapisu( const KopiaNapisu & Ob ): wNapis(NULL)
{ cout <<  ++ Konstruktor kopiujacy << endl; Zmien(Ob. wNapis); }
. . .
KopiaNapisu & operator = ( const KopiaNapisu & Ob ) { Zmien( Ob. wNapis ); }
. . .
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
int main( )
{
KopiaNapisu Ob1;
Ob1.Zmien( Ten tekst nic nie znaczy ;-) );
KopiaNapisu Ob2(Ob1);
KopiaNapisu Ob3 = Ob1;
}
Konstruktor kopiujÄ…cy
12
Konstruktor kopiujÄ…cy (raz jeszcze)
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
. . .
KopiaNapisu( const KopiaNapisu & Ob ): wNapis(NULL)
{ cout <<  ++ Konstruktor kopiujacy << endl; Zmien(Ob. wNapis); }
. . .
KopiaNapisu & operator = ( const KopiaNapisu & Ob ) { Zmien( Ob. wNapis ); }
. . .
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
int main( )
{
KopiaNapisu Ob1;
Ob1.Zmien( Ten tekst nic nie znaczy ;-) );
Wynik działania:
KopiaNapisu Ob2(Ob1);
++ Konstruktor kopiujacy
++ Konstruktor kopiujacy
KopiaNapisu Ob3 = Ob1;
}
Konstruktor kopiujÄ…cy
12
Konstruktor kopiujÄ…cy (raz jeszcze)
class KopiaNapisu { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
char " wNapis;
public :
. . .
KopiaNapisu( const KopiaNapisu & Ob ): wNapis(NULL)
{ cout <<  ++ Konstruktor kopiujacy << endl; Zmien(Ob. wNapis); }
. . .
KopiaNapisu & operator = ( const KopiaNapisu & Ob ) { Zmien( Ob. wNapis ); }
. . .
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
int main( )
{
KopiaNapisu Ob1;
Ob1.Zmien( Ten tekst nic nie znaczy ;-) );
Wynik działania:
KopiaNapisu Ob2(Ob1);
++ Konstruktor kopiujacy
++ Konstruktor kopiujacy
KopiaNapisu Ob3 = Ob1;
}
Przy inicjalizacji zawsze i wyłącznie wywoływane są konstruktory. W szczególności zapis operacji
przypisania odpowiada uruchomieniu operatora kopiujÄ…cego.
Konstruktor kopiujÄ…cy
13
Klasa z polami referencyjnymi
class KlasaZReferencja { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public :
int & PoleRef;
int PoleNor;
KlasaZReferencja( ): PoleRef( PoleNor ) { }
KlasaZReferencja( int & Zm ): PoleRef( Zm ) { }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
KlasaZReferencja Ob1, Ob2(Ob1. PoleNor);



KlasaZReferencja Ob3(Ob1);




Ob1
= Ob2;

}
Konstruktor kopiujÄ…cy
13
Klasa z polami referencyjnymi
class KlasaZReferencja { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public :
int & PoleRef;
int PoleNor;
KlasaZReferencja( ): PoleRef( PoleNor ) { }
KlasaZReferencja( int & Zm ): PoleRef( Zm ) { }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
KlasaZReferencja Ob1, Ob2(Ob1. PoleNor);



KlasaZReferencja Ob3(Ob1);




Ob1
= Ob2;

}
W przypadku klas zawierających pola referencyjne zarówno konstruktor kopiujący jak też operator
przypisania nie są domyślnie definiowane.
Konstruktor kopiujÄ…cy
14
Klasa z polami referencyjnymi (raz jeszcze)
class KlasaZReferencja { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public :
int & PoleRef;
int PoleNor;
KlasaZReferencja( ): PoleRef( PoleNor ) { }
KlasaZReferencja( int & Zm ): PoleRef( Zm ) { }
KlasaZReferencja( const KlasaZReferencja & Ob ): PoleRef( PoleNor) { . . . }
KlasaZReferencja & operator = (const KlasaZReferencja & Ob ) { . . . }
}; //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
KlasaZReferencja Ob1, Ob2(Ob1. PoleNor);
KlasaZReferencja Ob3(Ob1);
Ob1 = Ob2;
}
Konstruktor kopiujÄ…cy
14
Klasa z polami referencyjnymi (raz jeszcze)
class KlasaZReferencja { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public :
int & PoleRef;
int PoleNor;
KlasaZReferencja( ): PoleRef( PoleNor ) { }
KlasaZReferencja( int & Zm ): PoleRef( Zm ) { }
KlasaZReferencja( const KlasaZReferencja & Ob ): PoleRef( PoleNor) { . . . }
KlasaZReferencja & operator = (const KlasaZReferencja & Ob ) { . . . }
}; //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
KlasaZReferencja Ob1, Ob2(Ob1. PoleNor);
KlasaZReferencja Ob3(Ob1);
Ob1 = Ob2;
}
Zdefiniowanie konstruktora kopiujÄ…cego i operatora przypisania jest warunkiem koniecznym akcep-
tacji przez kompilator wyżej przedstawionych operacji. Dotyczy to również przekazywania obiektu
przez wartość jako parametru wywołania oraz jego zwracania przez funkcję/metodę.
Konstruktor kopiujÄ…cy
15
Podsumowanie (pola wskaznikowe)
" W przypadku klas, w których zdefiniowane są pola wskaznikowe, może ko-
niecznym okazać się zdefiniowanie konstruktora kopiującego oraz przecią-
żenie operatora przypisania. Jest to niezbędne wtedy, gdy obiekty tej klasy
stowarzyszone sÄ… ze strukturami tworzonymi dynamicznie i usuwanymi w
destruktorze.
Konstruktor kopiujÄ…cy
15
Podsumowanie (pola wskaznikowe)
" W przypadku klas, w których zdefiniowane są pola wskaznikowe, może ko-
niecznym okazać się zdefiniowanie konstruktora kopiującego oraz przecią-
żenie operatora przypisania. Jest to niezbędne wtedy, gdy obiekty tej klasy
stowarzyszone sÄ… ze strukturami tworzonymi dynamicznie i usuwanymi w
destruktorze.
" Jeżeli w destruktorze stowarzyszone z danym obiektem struktury danych nie
są poddawane destrukcji, to na ogół można ograniczyć się do domyślnej im-
plementacji konstruktora kopiujÄ…cego i operatora przypisania.
Konstruktor kopiujÄ…cy
16
Podsumowanie (pola referencyjne)
" W klasach, w których definiowane są pola referencyjne nie istnieje domyślna
implementacja konstruktora kopiujÄ…cego i operatora przypisania. Wynika to
z fakty, że zwykłe przepisanie bajt po bajcie zawartości obiektów zmieniałoby
referencje. Z definicji zaś referencji wynika, że w trakcie swojego istnienia nie
może ona ulegać zmianom.
Konstruktor kopiujÄ…cy
16
Podsumowanie (pola referencyjne)
" W klasach, w których definiowane są pola referencyjne nie istnieje domyślna
implementacja konstruktora kopiujÄ…cego i operatora przypisania. Wynika to
z fakty, że zwykłe przepisanie bajt po bajcie zawartości obiektów zmieniałoby
referencje. Z definicji zaś referencji wynika, że w trakcie swojego istnienia nie
może ona ulegać zmianom.
" Jeżeli obiekty klasy zawierającej pola referencyjne mają być przekazywane
jako parametr wywołania funkcji/metody lub przez nie zwracane lub też w
sposób jawny ma być wywoływany konstruktor kopiujący, to jego zdefiniowa-
nie jest bezwzględnie konieczne.
Konstruktor kopiujÄ…cy
16
Podsumowanie (pola referencyjne)
" W klasach, w których definiowane są pola referencyjne nie istnieje domyślna
implementacja konstruktora kopiujÄ…cego i operatora przypisania. Wynika to
z fakty, że zwykłe przepisanie bajt po bajcie zawartości obiektów zmieniałoby
referencje. Z definicji zaś referencji wynika, że w trakcie swojego istnienia nie
może ona ulegać zmianom.
" Jeżeli obiekty klasy zawierającej pola referencyjne mają być przekazywane
jako parametr wywołania funkcji/metody lub przez nie zwracane lub też w
sposób jawny ma być wywoływany konstruktor kopiujący, to jego zdefiniowa-
nie jest bezwzględnie konieczne.
" W przypadku, gdy ma być wykonywana operacja przypisania, konieczne jest
wówczas zdefiniowanie operatora przypisania.
Konstruktor kopiujÄ…cy
16
Podsumowanie (pola referencyjne)
" W klasach, w których definiowane są pola referencyjne nie istnieje domyślna
implementacja konstruktora kopiujÄ…cego i operatora przypisania. Wynika to
z fakty, że zwykłe przepisanie bajt po bajcie zawartości obiektów zmieniałoby
referencje. Z definicji zaś referencji wynika, że w trakcie swojego istnienia nie
może ona ulegać zmianom.
" Jeżeli obiekty klasy zawierającej pola referencyjne mają być przekazywane
jako parametr wywołania funkcji/metody lub przez nie zwracane lub też w
sposób jawny ma być wywoływany konstruktor kopiujący, to jego zdefiniowa-
nie jest bezwzględnie konieczne.
" W przypadku, gdy ma być wykonywana operacja przypisania, konieczne jest
wówczas zdefiniowanie operatora przypisania.
" Jeżeli wyżej wymienione operacje nie będą wykonywane, to nie ma potrzeby
definiowania zarówno konstruktora kopiującego, jak też operatora przypisa-
nia.
Konstruktor kopiujÄ…cy


Wyszukiwarka

Podobne podstrony:
08 Konstrukcje zbiorów liczbowych
konstrukcje metalowe 08 06
2002 08 Szkoła konstruktorówid!646
07 konstruktory?struktory prez
Konstrukcje metalowe – koo poprawkowe I (08 09 09) v 2
1997 08 Szkoła konstruktorów
08 zakres prez
2000 08 Szkoła konstruktorów
2010 08 Szkoła konstruktorów klasa III
08 Obliczanie obciążeń konstrukcji budowlanych
2000 08 Szkoła konstruktorów klasa II
Wyklad konstrukcja szczebla 08
1999 08 Szkoła konstruktorów klasa II
2003 08 Szkoła konstruktorów
1996 08 Szkoła konstruktorów
2003 08 Szkoła konstruktorów klasa II
1999 08 Szkoła konstruktorów

więcej podobnych podstron