Konstruktory i destruktory
Bogdan Kreczmer
ZPCiR IIAiR PWr
pokój 307 budynek C3
bogdan.kreczmer@pwr.wroc.pl
Copyright c
°
2005–2009 Bogdan Kreczmer
?
?
Niniejszy dokument zawiera materiały do wykładu na temat programowania obiektowego. Jest on udost ˛epniony pod
warunkiem wykorzystania wył ˛
acznie do własnych prywatnych potrzeb i mo˙ze on by´c kopiowany wył ˛
acznie w cało´sci, razem z
niniejsz ˛
a stron ˛
a tytułow ˛
a.
1
Inicjalizacja obiektu
Kto zgadnie co ten program wy´swietli?
>
8-|
#
include
<
iostream
>
using namespace std;
struct Wektor { float x, y; };
int main()
{
Wektor W;
cout
<<
W. x
<<
", "
<<
W. y
<<
endl;
}
Konstruktory i destruktory
1
Inicjalizacja obiektu
Kto zgadnie co ten program wy´swietli?
>
8-|
#
include
<
iostream
>
using namespace std;
struct Wektor { float x, y; };
int main()
{
Wektor W;
cout
<<
W. x
<<
", "
<<
W. y
<<
endl;
}
Jedno jest pewne. Tego nikt nie zgadnie. ;-)
Konstruktory i destruktory
2
Inicjalizacja obiektu
#
include
<
iostream
>
using namespace std;
struct Wektor { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor() { x = 0; y = 0; }
// . . .
Ta metoda inicjalizuje obiekt.
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main()
{
Wektor
W;
cout
<<
W. x
<<
”, ”
<<
W. y
<<
endl;
}
Konstruktory i destruktory
2
Inicjalizacja obiektu
#
include
<
iostream
>
using namespace std;
struct Wektor { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor() { x = 0; y = 0; }
// . . .
Ta metoda inicjalizuje obiekt.
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main()
{
Wektor
W;
cout
<<
W. x
<<
”, ”
<<
W. y
<<
endl;
}
Teraz sposób inicjalizacji jest ju˙z jednoznacznie okre´slony.
Konstruktory i destruktory
3
Konstruktory
. . .
struct Wektor { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor() { x = 0; y = 0; }
Wektor( float x, float y) { x = x; y = y; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main()
{
Wektor
W(4,5);
// . . . . .
Inicjalizujemy obiekt tak jak chcemy.
cout
<<
W. x
<<
”, ”
<<
W. y
<<
endl;
}
Konstruktory i destruktory
3
Konstruktory
. . .
struct Wektor { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor() { x = 0; y = 0; }
Wektor( float x, float y) { x = x; y = y; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main()
{
Wektor
W(4,5);
// . . . . .
Inicjalizujemy obiekt tak jak chcemy.
cout
<<
W. x
<<
”, ”
<<
W. y
<<
endl;
}
Konstruktory pozwalaj ˛
a na wybór sposobu inicjalizacji obiektu.
Konstruktory i destruktory
4
Konstruktory
. . .
struct Wektor { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor( float x, float y) { x = x; y = y; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main()
{
Wektor
hhh
hh
h
((
((
(
(
V;
// . . . . . . .
Taka deklaracja jest teraz zabroniona.
Wektor
W(4,5);
. . .
}
Konstruktory i destruktory
4
Konstruktory
. . .
struct Wektor { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor( float x, float y) { x = x; y = y; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main()
{
Wektor
hhh
hh
h
((
((
(
(
V;
// . . . . . . .
Taka deklaracja jest teraz zabroniona.
Wektor
W(4,5);
. . .
}
Deklaracja konstruktora uniewa˙znia konstruktor domy´slny.
Konstruktory i destruktory
5
Konstruktory
. . .
struct Wektor { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor( float x = 0, float y = 0) { x = x; y = y; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main()
{
Wektor
V;
// . . . .
Teraz deklaracja ta jest ju˙z dopuszczalna.
Wektor
W(4,5);
. . .
}
Konstruktory i destruktory
5
Konstruktory
. . .
struct Wektor { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor( float x = 0, float y = 0) { x = x; y = y; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main()
{
Wektor
V;
// . . . .
Teraz deklaracja ta jest ju˙z dopuszczalna.
Wektor
W(4,5);
. . .
}
Konstruktory, podobnie jak metody, mog ˛
a zawiera´c domy´slne warto´sci parametrów.
Konstruktory i destruktory
6
Konstruktory
. . .
struct Wektor { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor( float x, float y) { x = x; y = y; }
private :
Wektor() { x = y = 0; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main()
{
Wektor
hhh
hh
h
((
((
(
(
V;
//
Ponownie deklaracja ta staje si ˛e niedopuszczalna.
Wektor
W(4,5);
. . .
}
Konstruktory i destruktory
6
Konstruktory
. . .
struct Wektor { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor( float x, float y) { x = x; y = y; }
private :
Wektor() { x = y = 0; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main()
{
Wektor
hhh
hh
h
((
((
(
(
V;
//
Ponownie deklaracja ta staje si ˛e niedopuszczalna.
Wektor
W(4,5);
. . .
}
Sekcja private i protected pozwalaj ˛
a uniemo˙zliwi´c korzystanie z wybranych kon-
struktorów na poziomie publicznym.
Konstruktory i destruktory
7
Konstruktory
. . .
struct Wektor {
float
x, y;
. . .
Wektor Dodaj(constWektor
∗
pW);
private :
Wektor() { x = y = 0; } //
Ta deklaracja uniemo˙zliwia deklaracji obiektu poza dan ˛
a klas ˛
a.
};
Wektor Wektor ::Dodaj( constWektor
∗
pW)
{
Wektor
W;
// . . . . . . . . . .
Tutaj mo˙zna korzysta´c z prywatnego konstruktora.
W. x = x + pW–
>
x;
W. y = y + pW–
>
y;
return W;
}
. . .
Konstruktory i destruktory
7
Konstruktory
. . .
struct Wektor {
float
x, y;
. . .
Wektor Dodaj(constWektor
∗
pW);
private :
Wektor() { x = y = 0; } //
Ta deklaracja uniemo˙zliwia deklaracji obiektu poza dan ˛
a klas ˛
a.
};
Wektor Wektor ::Dodaj( constWektor
∗
pW)
{
Wektor
W;
// . . . . . . . . . .
Tutaj mo˙zna korzysta´c z prywatnego konstruktora.
W. x = x + pW–
>
x;
W. y = y + pW–
>
y;
return W;
}
. . .
Sekcje private i protected nie ograniczaj ˛
a dost ˛epu do konstruktorów oraz innych
metod i pól na poziomie metod danej klasy.
Konstruktory i destruktory
8
Prywatny konstruktor
struct KlasaSkladowa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
private :
KlasaSkladowa( ) { }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
struct KlasaFinalna { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladowa
Pole;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main()
{
KlasaFinalna ObKlasyF;
}
Czy ten obiekt mo˙zna utworzy´c?
Konstruktory i destruktory
9
Prywatny konstruktor
struct KlasaSkladowa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
friend class KlasaFinalna;
private :
KlasaSkladowa( ) { }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
struct KlasaFinalna { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladowa
Pole;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main()
{
KlasaFinalna ObKlasyF;
}
Do konstruktorów stosuj ˛
a si ˛e wszystkie reguły i mechanizmy dost ˛epu jakie wykorzystywane s ˛
a w
przypadku zwykłych metod.
Konstruktory i destruktory
10
Konstruktory
. . .
struct Wektor { //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor() { x = y = 0; }
Wektor( float x, float y ) { x = x; y = y; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
Wektor
Tab1[3];
Wektor
Tab2[3] = {
Wektor(1,1), Wektor(2,1), Wektor(4,2) };
Wektor
Tab3[3] = {
Wektor(2,2) };
Wektor
Tab4[3] = {
Wektor(2,2), Wektor(), Wektor(5,5) };
. . .
Konstruktory i destruktory
10
Konstruktory
. . .
struct Wektor { //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor() { x = y = 0; }
Wektor( float x, float y ) { x = x; y = y; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
Wektor
Tab1[3];
Wektor
Tab2[3] = {
Wektor(1,1), Wektor(2,1), Wektor(4,2) };
Wektor
Tab3[3] = {
Wektor(2,2) };
Wektor
Tab4[3] = {
Wektor(2,2), Wektor(), Wektor(5,5) };
. . .
Przy deklarowaniu tablic domy´slnie u˙zywany jest konstruktor bezparametryczny.
Konstruktory i destruktory
11
Konstruktory
. . .
struct Wektor {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor( ) { x = y = 0; }
Wektor( float x, float y ) { x = x; y = y; }
};
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Wektor Dodaj1( Wektor W1, Wektor W2 )
{
W1. x += W2. x; W1. y += W2. y;
return W1;
}
Wektor Dodaj2( Wektor W1, Wektor W2 )
{
Wektor
W(W1. x+W2. x, W1. y+W2. y);
return W; }
Wektor Dodaj3( Wektor W1, Wektor W2 )
{
return Wektor(W1. x+W2. x, W1. y+W2. y);
}
. . .
Konstruktory i destruktory
11
Konstruktory
. . .
struct Wektor {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor( ) { x = y = 0; }
Wektor( float x, float y ) { x = x; y = y; }
};
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Wektor Dodaj1( Wektor W1, Wektor W2 )
{
W1. x += W2. x; W1. y += W2. y;
return W1;
}
Wektor Dodaj2( Wektor W1, Wektor W2 )
{
Wektor
W(W1. x+W2. x, W1. y+W2. y);
return W; }
Wektor Dodaj3( Wektor W1, Wektor W2 )
{
return Wektor(W1. x+W2. x, W1. y+W2. y);
}
. . .
Konstruktory pozwalaj ˛
a tak˙ze na bardziej zwi ˛ezły zapis i lepsz ˛
a implementacj ˛e funkcji i metod.
Konstruktory i destruktory
12
Lista inicjalizacyjna
class PrzykladKlasy { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int
Pole;
public :
PrzykladKlasy( );
}; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Konstruktory i destruktory
12
Lista inicjalizacyjna
class PrzykladKlasy { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int
Pole;
public :
PrzykladKlasy( );
}; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Dwie mo˙zliwe implementacje konstruktora
PrzykladKlasy::PrzykladKlasy( )
{
Pole = 0;
}
PrzykladKlasy::PrzykladKlasy( ): Pole(0)
{ }
Pole klasy mo˙ze zosta´c zainicjalizowane na dwa sposoby, albo w ciele konstruktora, albo te˙z poprzez
list ˛e inicjalizacyjn ˛
a. Niektóre rodzaje pól mog ˛
a by´c zainicjalizowane tylko i wył ˛
acznie z poziomu listy
inicjalizacyjnej.
Konstruktory i destruktory
13
Lista inicjalizacyjna - ró˙znice i podobie ´
nstwa
int Zmienna;
Zmienna = 0;
int Zmienna = 0;
PrzykladKlasy::PrzykladKlasy( )
{
Pole = 0;
}
PrzykladKlasy::PrzykladKlasy( ): Pole(0)
{ }
Umieszczenie inicjalizatora w li´scie inicjalizacyjnej konstruktora powoduje przypisanie warto´sci polu
w momencie jego utworzenia.
Konstruktory i destruktory
14
Lista inicjalizacyjna
class PrzykladKlasy { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int
Pole;
public :
PrzykladKlasy( int Param );
}; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
PrzykladKlasy::PrzykladKlasy( int Param ): Pole(Param)
{ }
Do inicjalizatorów mo˙zna przekaza´c warto´s´c poprzez parametr wywołania konstruktora.
Konstruktory i destruktory
15
Lista inicjalizacyjna
class PrzedzialLiczb { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int
WartoscMini;
int
WartoscMaks;
public :
PrzedzialLiczb( int Mini, int Maks );
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
PrzedzialLiczb::PrzedzialLiczb( int Mini, int Maks ):
WartoscMini(Mini), WartoscMaks(Maks)
{ }
Lista inicjalizacyjna mo˙ze zawiera´c dowoln ˛
a ilo´s´c inicjalizatorów. Uruchamiane s ˛
a one w kolejno´sci
tworzenia pól, która jest zgodna z porz ˛
adkiem ich deklaracji w klasie. Nie jest bł ˛edem podanie ini-
cjalizatorów w innej kolejno´sci. Jednak nie wpłynie ona na kolejno´s´c ich wywoła ´n.
Aby nie wprowadza´c nieporozumie ´n, kolejno´s´c inicjalizatorów powinna zawsze odpowiada´c faktycz-
nej kolejno´sci ich uruchamiania.
Konstruktory i destruktory
16
Lista inicjalizacyjna
class PrzedzialLiczb { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int
WartoscMini;
int
WartoscMaks;
public :
PrzedzialLiczb( int Mini, int Maks );
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
PrzedzialLiczb::PrzedzialLiczb( int Mini, int Maks ):
WartoscMini(), WartoscMaks()
{ }
A teraz jak ˛
a warto´sci ˛
a zostan ˛
a zainicjalizowane pola klasy?
Konstruktory i destruktory
17
Konstruktor i destruktor
struct PustaKlasa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
PustaKlasa( ) { cout
<<
”++PustaKlasa”
<<
endl; }
∼
PustaKlasa( ) { cout
<<
”
−−
PustaKlasa”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
cout
<<
”Witajcie !!! :-)”
<<
endl;
PustaKlasa Ob;
cout
<<
”Zegnajcie !!! :-(”
<<
endl;
}
Konstruktory i destruktory
17
Konstruktor i destruktor
struct PustaKlasa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
PustaKlasa( ) { cout
<<
”++PustaKlasa”
<<
endl; }
∼
PustaKlasa( ) { cout
<<
”
−−
PustaKlasa”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
cout
<<
”Witajcie !!! :-)”
<<
endl;
PustaKlasa Ob;
cout
<<
”Zegnajcie !!! :-(”
<<
endl;
}
Wynik działania:
Witajcie !!!
:-)
++PustaKlasa
Zegnajcie !!!
:-(
−−PustaKlasa
W przypadku zmiennych lokalnych (automatycznych) konstruktor wywoływany jest w chwili tworze-
nia obiektu, tj. w miejscu jego deklaracji. Destruktor natomiast jest wywoływany w miejscu ko ´nca
zakresu wa˙zno´sci deklaracji.
Konstruktory i destruktory
18
Konstruktory w klasach zło˙zonych
struct KlasaSkladnikaA { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladnikaA( ) { cout
<<
”++KlasaSkladnikaA”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
struct KlasaSkladnikaB { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladnikaB( ) { cout
<<
”++KlasaSkladnikaB”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
struct KlasaFinalna { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladnikaA
PoleA;
KlasaSkladnikaB
PoleB;
KlasaFinalna( ) { cout
<<
”++KlasaFinalna”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
KlasaFinalna Ob;
}
Konstruktory i destruktory
18
Konstruktory w klasach zło˙zonych
struct KlasaSkladnikaA { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladnikaA( ) { cout
<<
”++KlasaSkladnikaA”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
struct KlasaSkladnikaB { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladnikaB( ) { cout
<<
”++KlasaSkladnikaB”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
struct KlasaFinalna { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladnikaA
PoleA;
KlasaSkladnikaB
PoleB;
KlasaFinalna( ) { cout
<<
”++KlasaFinalna”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
KlasaFinalna Ob;
}
Wynik działania:
++KlasaSkladnikaA
++KlasaSkladnikaB
++KlasaFinalna
Pola tworzone s ˛
a zgodnie z kolejno´sci ˛
a ich deklaracji.
Konstruktory i destruktory
19
Konstruktory i destruktory w klasach zło˙zonych
struct KlasaSkladnikaA { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladnikaA( ) { cout
<<
”++KlasaSkladnikaA”
<<
endl; }
∼
KlasaSkladnikaA( ) { cout
<<
”
−−
KlasaSkladnikaA”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
struct KlasaSkladnikaB { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladnikaB( ) { cout
<<
”++KlasaSkladnikaB”
<<
endl; }
∼
KlasaSkladnikaB( ) { cout
<<
”
−−
KlasaSkladnikaB”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
struct KlasaFinalna { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladnikaA
PoleA;
KlasaSkladnikaB
PoleB;
KlasaFinalna( ) { cout
<<
”++KlasaFinalna”
<<
endl; }
∼
KlasaFinalna( ) { cout
<<
”
−−
KlasaFinalna”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
KlasaFinalna Ob;
cout
<<
”Witajcie i zegnajcie !!!”
<<
endl;
}
Konstruktory i destruktory
19
Konstruktory i destruktory w klasach zło˙zonych
struct KlasaSkladnikaA { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladnikaA( ) { cout
<<
”++KlasaSkladnikaA”
<<
endl; }
∼
KlasaSkladnikaA( ) { cout
<<
”
−−
KlasaSkladnikaA”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
struct KlasaSkladnikaB { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladnikaB( ) { cout
<<
”++KlasaSkladnikaB”
<<
endl; }
∼
KlasaSkladnikaB( ) { cout
<<
”
−−
KlasaSkladnikaB”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
struct KlasaFinalna { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
KlasaSkladnikaA
PoleA;
KlasaSkladnikaB
PoleB;
KlasaFinalna( ) { cout
<<
”++KlasaFinalna”
<<
endl; }
∼
KlasaFinalna( ) { cout
<<
”
−−
KlasaFinalna”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
KlasaFinalna Ob;
cout
<<
”Witajcie i zegnajcie !!!”
<<
endl;
}
Wynik działania:
++KlasaSkladnikaA
++KlasaSkladnikaB
++KlasaFinalna
”Witajcie i zegnajcie !!!”
−−KlasaFinalna
−−KlasaSkladnikaB
−−KlasaSkladnikaA
Konstruktory i destruktory
20
Konstruktory — lista inicjalizacji
. . .
struct Wektor { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor( ) { x = y = 0; }
Wektor( float x, float y ) { x = x; y = y; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
struct Odcinek { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Wektor Po, Pn;
Odcinek( );
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Odcinek::Odcinek( ): Po(-1,-1), Pn(1,1) //
Lista inicjalizuj ˛
aca wymusza wywołanie konstruktorów
{ }
. . .
Konstruktory i destruktory
20
Konstruktory — lista inicjalizacji
. . .
struct Wektor { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
x, y;
Wektor( ) { x = y = 0; }
Wektor( float x, float y ) { x = x; y = y; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
struct Odcinek { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Wektor Po, Pn;
Odcinek( );
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Odcinek::Odcinek( ): Po(-1,-1), Pn(1,1) //
Lista inicjalizuj ˛
aca wymusza wywołanie konstruktorów
{ }
. . .
Lista inicjalizuj ˛
aca pozwala wymusi´c wywołanie zadanego konstruktora dla poszczególnych składni-
ków obiektu. Kolejno´s´c składników listy powinna odpowiada´c kolejno´sci deklaracji pól klasy.
Konstruktory i destruktory
21
Obiekty tworzone w sposób dynamiczny
struct PustaKlasa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
PustaKlasa( ) { cout
<<
”++PustaKlasa”
<<
endl; }
∼
PustaKlasa( ) { cout
<<
”
−−
PustaKlasa”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
cout
<<
”Witajcie !!! :-)”
<<
endl;
PustaKlasa
∗
wOb =
new PustaKlasa;
cout
<<
”Zegnajcie !!! :-(”
<<
endl;
}
Konstruktory i destruktory
21
Obiekty tworzone w sposób dynamiczny
struct PustaKlasa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
PustaKlasa( ) { cout
<<
”++PustaKlasa”
<<
endl; }
∼
PustaKlasa( ) { cout
<<
”
−−
PustaKlasa”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
cout
<<
”Witajcie !!! :-)”
<<
endl;
PustaKlasa
∗
wOb =
new PustaKlasa;
cout
<<
”Zegnajcie !!! :-(”
<<
endl;
}
Wynik działania:
Witajcie !!!
:-)
++PustaKlasa
Zegnajcie !!!
:-(
W przypadku obiektów tworzonych w sposób dynamiczny, to programista decyduje kiedy je znisz-
czy´c. Zako ´nczenie programu bez wykonania tej operacji nie spowoduje automatycznego urucho-
mienia destruktorów tych obiektów.
Konstruktory i destruktory
22
Obiekty tworzone w sposób dynamiczny
struct PustaKlasa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
PustaKlasa( ) { cout
<<
”++PustaKlasa”
<<
endl; }
∼
PustaKlasa( ) { cout
<<
”
−−
PustaKlasa”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
cout
<<
”Witajcie !!! :-)”
<<
endl;
PustaKlasa
∗
wOb =
new PustaKlasa;
delete wOb;
cout
<<
”Zegnajcie !!! :-(”
<<
endl;
}
Konstruktory i destruktory
22
Obiekty tworzone w sposób dynamiczny
struct PustaKlasa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
PustaKlasa( ) { cout
<<
”++PustaKlasa”
<<
endl; }
∼
PustaKlasa( ) { cout
<<
”
−−
PustaKlasa”
<<
endl; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
cout
<<
”Witajcie !!! :-)”
<<
endl;
PustaKlasa
∗
wOb =
new PustaKlasa;
delete wOb;
cout
<<
”Zegnajcie !!! :-(”
<<
endl;
}
Wynik działania:
Witajcie !!!
:-)
++PustaKlasa
−−PustaKlasa
Zegnajcie !!!
:-(
Operator
delete mo˙zna zastosowa´c tylko do zmiennej wska´znikowej w dowolnym miejscu programu.
Jedynym warunkiem poprawno´sci jego wywołania jest to, aby pod danym adresem istniał obiekt
utworzony dynamicznie z wykorzystaniem operatora
new.
Konstruktory i destruktory
23
Obiekty tworzone w sposób dynamiczny
struct PustaKlasa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
PustaKlasa( ) { }
∼
PustaKlasa( ) { }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
int
∗
wTab =
new int[ 30 ];
PustaKlasa
∗
wOb =
new PustaKlasa[ 20 ];
delete [ ] wTab;
delete [ ] wOb;
}
W przypadku tworzenia w sposób dynamiczny tablic obiektów stosuj ˛
ac operator
delete nale˙zy jawnie
wskaza´c, ˙ze usuwana jest tablica obiektów, a nie pojedynczy obiekt. Rozmiar tablicy nie jest istotny.
Konstruktory i destruktory
24
Pytania i ´cwiczenia
1. Dana jest nast ˛epuj ˛
aca definicja klasy
class Wektor {
float
x,
y;
private:
Wektor() {
x = y = 0; }
protected:
Wektor(
float xx, float yy ) {
x = xx;
y = yy; }
};
Czy obiekt klasy
Wektor zdefiniowany jak wy˙zej, mo˙zna zadeklarowa´c funkcji
main
?
Czy
mo˙zna go zadeklarowa´c jako obiekt globalny (tzn. jako zmienn ˛
a globaln ˛
a).
Konstruktory i destruktory