Wykªad 3. Konstruktory(uzupeªnienie), zas»y ia obiektów,
operatory,konwersjetypów
przypomnienie
◮
Konstruktortospe jalna metodawywoªywana (automaty znie
lubjawnie)w momen ietworzenia obiektu.
◮
Nazwakonstruktorajesttakajaknazwaklasy.◮
Konstruktornie zwra a warto± i,mo»e mie¢ argumenty,mo»e
by¢przeªadowany.
peªnaskªadnia
nazwa(argumenty) : lista_ini jaliza yjna
{
instruk je
}
Listaini jaliza yjna zawiera sekwen j ini jalizatorow.
Ini jalizatoremmo»eby¢:
◮
atrybut(wyra»enie)zaini jalizowanieatrybutu(niestaty znego)warto± i¡
wyra»enia.
◮
atrybut(lista_parametrów_konstruktora)zaini jalizowanieatrybutu(niestaty znego)zapomo ¡jego
konstruktora
◮
ini jaliza jastaªej
lass A
{
onst int stala; // tu nie mo»na zaini jalizowa¢ staªej
A() : stala(0) // tylko tu mo»na zaini jalizowa¢ staª¡
{
// tu nie mo»na zaini jalizowa¢ staªej
}
};
ini jaliza jaatrybutuniebd¡ egostaª¡
lass A
{
int a,b, ; // tu nie mo»na zaini jalizowa¢
A() : a(1), (0) // mo»na tu
{
b=1; // albo tu
}
}
ini jaliza jaatrybutubd¡ egoreferen j¡
lass A
{
B& b;
A(B& bref) : b(bref)
{
// tu ju» nie mo»na manipulowa¢ warto± i¡ b
}
};
konstruk ja z± idziedzi zonejobiektu
lass A
{
int a;
A(int i) a(i) : { } // konstruktor w klasie A
}
lass B : publi A // B jest podklas¡ A
{
int b;
B(int i, int j) : A(i), // wywoªanie konstruktora nadklasy
b(j) // ini jaliza ja niedziedzi zonego atrybutu b
{ }
};
◮
Jest tospe jalny konstruktor, konstuuj¡ yobiekt na podstawie
podanegojako argument wzor a.
◮
Jego jedynyargument jesttypu referena jado obiektutejsamejklasy.
◮
Konstruktorkopiuj¡ y zazwy zaj niemapotrzeby dokonywa¢zmian we wzor u, dlategozwykle u»ywasi referen jido
obiektustaªego.
lass K
{
K(K& k) {...}
// lub K( onst K& k) {...}
przykªad
lass Osoba
{
har* imie;
Osoba( onst Osoba& o)
{
imie = new har[strlen(o.imie)+1℄;
str py(imie, o.imie);
}
};
W powy»szymprzykªadzie atrybutimiew nowym obiek iepowinien
wskazywa¢ nawªasn¡ kopiimienia. Automaty zniewygenerowany
konstruktorkopiuj¡ y skopiowaªby wska¹nik, o mogªoby mie¢
konstruktorkopiuj¡ ygenerowanyautomaty znie
◮
Je±linie zdeniujemykonstruktora kopiuj¡ ego generowany
jeston automaty znie.
◮
Automaty znie wygenerowany konstruktorkopiuj¡ y,kopiuje
obiekt skªadnik po skªadniku,z wykorzystaniem - tamgdzie
mamy do zynienie zobiektami- konstruktorówkopiuj¡ y hz
odpowiedni hklas.
◮
W wikszo± iprzypadkow takikonstruktorkopiuj¡ ywystar za.
wywoªaniejawne
Osoba o,o1; // o jest obiektem klasy Osoba
...
o1 = Osoba(o); // o1 ma by¢ kopi¡ obiektu o
wywoªanieniejawne
Konstruktorkopiuj¡ y jestniejawnie wywoªywany w dwó h
przypadka h:
◮
kiedyobiekt jestprzekazywany jakoparametrfunk ji/metody
przezwarto±¢
◮
kiedyfunk ja/metoda zwra a jakowarto±¢ obiektlass Osoba
{
...
Osoba sklonuj(Osoba o) // przekazanie obiektu przez warto±¢,
// do metody trafi kopia argumentu
{
Osoba o1 = Osoba(o);
return o1; // zwra ana jest kopia obiektu lokalnego o1
}
...
}
konstruktordomniemany
◮
Konstruktordomniemany tokonstruktor, który mo»nauru homi¢bez argumentów (mo»etoby¢konstruktorz
argumentami domy±lnymi).
◮
Je±linie zdeniujemy»adnego konstruktora dlaklasy to ma
ona konstruktordomniemany wygenerowany automaty znie.
◮
Je±lizdeniujemy konstruktor(y)inie bdziew±ródni h
takiego, którymo»na uru homi¢bezargumentów, toklasanie
makonstruktora domniemanego. Trzeba pamita¢,»ew
pewny h sytua ja h brak konstruktora domniemanego
powoduje bª¡d.
kolejno±¢wykonywaniadziaªa«
1. uru homienie konstruktora nadklasy(je±liklasajestklas¡
po hodn¡)
◮
je±likonstruktorandklasy niewyminili±mynali± ie
ini jaliza yjnejuru hamiany jestkonstruktordomniemany
(bezargumentowy)
2. uru homienie konstruktorów obiektów skªadowy h
◮
obiektyskªadowekonstruowanes¡zgodniez zawarto± i¡listy
ini jaliza yjnej
◮
je±linali± ieini jaliza yjnejniewskazali±mykonstruktoradla
jakiego±obiektuskªadowego,uru hamianyjestjego
konstruktordomniemany(bezargumentowy)
3. wykonaniepozostaªy h zynno± izdeniowany h w iele
konstruktora
Tworzenieobiektówautomaty zny h
Obiekty automaty zne maj¡zakesbloku, istniej¡od momentu
deklara jido ko« abloku, wktórymzostaªyzadeklarowane.
lass A // jaka± klasa
{
...
A() {} // jej konstruktor bezargumentowy
A(int n) { ... } // i jej konstruktor z argumentem
};
int main()
{
...
{
A a; // deklara ja zm. z wywoªaniem konstruktora bezargumentowego
A b(5); // deklara ja zm. z wywoªaniem konstruktora z argumentem
...
} //tu ko« zy si zakres (i »ywot) a i b
...
Tworzenieobiektówglobalny h
Obiekty globalnemaj¡zakres pliku,istniej¡przez aªy zas
wykonywania programu. S¡ tworzone przedrozpo z iem
wykonywania funk ji main, ko« z¡ »ywot pojejzako« zeniu.
lass A // jaka± klasa
{
...
A() {} // jej konstruktor bezargumentowy
A(int n) { ... } // i jej konstruktor z argumentem
};
A a;
int main()
{
...
}
Dynami znetworzenieobiektów
Obiekt dynami zny istniej¡od momentujegoutworzenia za
pomo ¡operatora new do momentujegoznisz zenia operatorem
delete. Jestdostpny je±liistniejeijestdostpna jaka± zmienna
prze howyj¡ a wska¹nik doniego.
lass A // jaka± klasa
{
...
A() {} // jej konstruktor bezargumentowy
A(int n) { ... } // i jej konstruktor z argumentem
...
};
int main()
{
A* a = new A; // new A przydziela pami¢ na obiekt klasy A
// i zwra a wska¹nik do niego, obiekt jest
// tworzony przez konstruktor bezargumentowy
B* b = new A(5); // j.w. ale zadzaiªa konstruktor z argumentem
...
delete a; // utworzony dynami znie obiekt TRZEBA ZNISZCZY
delete b; // kiedy jest ju» niepotrzebny
Tworzenieobiektów hwilowy h
◮
Konstruktormo»na wywoªa¢ jawnie tak,jakby byªzwykª¡funk j¡ zwra aj¡ ¡ obiekt. Obiekt takijest' hwilowy' (=
istniej¡ y tylko wobrbie wyra»eniaw którymgo utworzono).
◮
U»y ie obiektów hwilowy h przypomina u»y iestaªy h
dosªowny h (literaªów),jak 13.5 'A'"Alamakota"
Tworzenieobiektów hwilowy h: przykªad
lass A // jaka± klasa
{
...
A() { } // jej konstruktor bezargumentowy
A(int n) { ... } // i jej konstruktor z argumentem
A f() // jaka± metoda zwra aj¡ a obiekt klasy A
{
...
return A(0); // jawne wywoªanie konstruktora tworzy obiekt
// hwilowy, który jest zwra any przez metod
}
};
int main()
{
A a = A(); // obiekt hwilowy zwró ony przez konstruktor jest
// przypisywany zmiennej a;
A b;
b = A(3); // j.w. (zmiennej b)
a = f(); // obiekt hwilowy zwró ony przez f() jest przypisywany
// zmiennej a
◮
W jzyku C++mamymo»liwo±¢deniowaniaoperatorów.
◮
Te hni znie, polega tona przeªadowaniu istniej¡ y h
operatorów, zdeniowaniu i h dziaªaniadlainny h typów
argumentów.
◮
Operatory mo»nadeniowa¢jako metodyklasy lubjakofunk je nazewn¡trzklasy. Deni jeoperatorów maj¡posta¢
tak¡ sam¡jakdeni je metod/funk ji,z t¡ró»ni ¡, »ew
mies unazwy metody/funk ji piszemy:
operatorX
gdzieXjest jednym zoperatorów:
+ - * / % ^ & | ~ ! = < >
+= -= *= /= %= ^= &= |= << = <<=
== != <= >= && || ++ , ->* ->
new delete () [℄
◮
przykªad:deni jaoperatoradwuargumentowego
lass Zespolona {
publi :
float re, im;
Zespolona() : re(0), im(0) { }
Zespolona(float r, float i) : re(r), im(i) { }
//defini ja operatora w posta i metody:
Zespolona operator+(Zespolona z) { return Zespolona(re+z.re, im+z.im); }
};
// defini ja operatora w posta i funk ji
Zespolona operator-(Zespolona z1, Zespolona z2)
{ return Zespolona(z1.re+z2.re, z1.im+z2.im); }
int main() {
Zespolona a(1,2), b(3,0), , d
= a + b;
d = - Zespolona(1,0);
}
deni jaoperatorajednoargumentowegopreksowego
lass Zespolona {
...
Zespolona operator-() { return Zespolona(-re,im); }
};
Zespolona operator-(Zespolona z) { return Zespolona(-z.re,im); }
operatorprzypisania
Operatorprzypisania mastatussz zególny. Jestjedyn¡
niedziedzi zon¡metod¡klasy(pozakonstruktoramiidestruktorem).
lass K
{
K& operator=(K& k) {...}
// lub K& operator=( onst K& k) {...}
}
Czsto stosowan¡praktyk¡ jestzabezpie zanie argumentu
operatora przypisania przedmo»liwo± i¡modyka jiZAWSZE.
(Niekonsekwentne stosowanie onstprowadzido kªopotów).
operatorprzypisaniagenerowanyautomaty znie
◮
Je±linie zdeniujemyoperatora przypisania generowany jeston
automaty znie.
◮
Automaty znie wygenerowany operatorprzypisania,dokonuje
przypisania skªadnikpo skªadniku,z wykorzystaniem - tam
gdziemamy do zynienie zobiektami- operatorów przypisania
z odpowiedni h klas.
◮
W wikszo± iprzypadkow takioperatorprzypisania wystar za.
operatorprzypisania: przykªad
lass Osoba
{
...
Osoba& operator=( onst Osoba& o)
{
if(imie!=NULL) // je±li obiekt ma imie
delete[℄ o.imie; // znisz z stare imie (zwolnij pami¢)
imie = new har[strlen(o.imie)+1℄; // zdob¡d¹ pami¢ na nowe imie
str py(imie, o.imie); // i przekopiuj je tam
}
...
publi :
har* imie;
}
przeªadowanieoperatora<<dlastumieniawyj± iowego
#in lude<iostream>
using namespa e std;
lass Zespolona {
publi :
Zespolona(double r, double i) : _re(r), _im(i) {}
double re() { return _re; }
double im() { return _im; }
private:
double _re,_im;
};
ostream& operator<<(ostream& os, Zespolona z) {
os << "(" << z.re() << "," << z.im() << ")";
return os;
}
int main() {
Zespolona z(1, 2.5);
out << z; // na wyj± iu: (1,2.5)
◮
W jzyku C++programista mo»e zdeniowa¢ reguªykonwersji
typów jakiemaj¡ by¢ stosowane dla obiektówklasprzez niego
deniowany h.
◮
Zdeniowane wten sposóbkonwersjemog¡by¢u»yte jawnie,z wykorzystaniem operatora konwersji (typ).
◮
S¡ te»u»ywane niejawnie przezkompilatorw trak iedopasowywania wywoªaniafunk ji/metody,stanowi¡
uzupeªnienie konwersji predeniowany h.
konwersjazdeniowanaprzezkonstruktor
Konstruktorz jednym argumentemokre±lakonwersjz typu tego
argumentunatypswojejklasy.
lass Zespolona
{
...
Zespolona(double f) re(f), im(0) : { } // konwersja z double na Zespolona
...
private:
double re,im;
};
int main()
{
Zespolona z1,z2,z3;
z1 = Zespolona(2.5); // zwykªe wywoªanie konstruktora
z2 = (Zespolona)0; // jawnie wywoªana konwersja
z3 = 5.0; // niejawna konwersja z double na Zespolona
z4 = 5; // int -> double -> Zespolona
konwersjazdeniowanaprzezoperatorkonwersji
Operatorbezargumentowy T(),którego nazwa Tjestnazw¡typu
defninuje konwersjez typu swojejklasy natypT.
lass Zespolona
{
...
operator double() { return re; } // konwersja z Zespolona na double
...
private:
float re,im;
};
int main()
{
Zespolona z(1,-1.5);
double x = (double)z; // jawna konwersja
double y = z; // niejawna konwersja z Zespolona na double
out << z; // niejawna konwersja z Zespolona na double
UWAGA!
Przy deniowaniu konwersji trzebaza howa¢ ostro»no±¢:
je±likomiplatornapotka niejednozna zno±¢(bdziemógªdokona¢
konwersji nawi ejni» jeden sposób) zgªosi bª¡d.
lass Zespolona
{
...
operator double() { return re; } // konwersja z Zespolona na double
operator int() { return (int)re; } // konwersja z Zespolona na int
...
private:
float re,im;
};
int main()
{
Zespolona z(1,-1.5);
double x = (double)z; // jawna konwersja
double y = z; // niejawna konwersja z Zespolona na double
out << z; // bª¡d! Zespolona->double zy Zespolona->int ?