370 likes | 525 Views
Osztály és objektum fogalma. Az osztály (class). class: adatok és módszerek (method) (függvények) együttese, amely absztrakt adattípusként működik. objektum: egy osztály egy előfordulása módszer: az osztály egy eleme. Olyan függvény, amely az osztályba tartozó adatokon manipulál.
E N D
Osztály és objektum fogalma A C++ programozási nyelv I.
Az osztály (class) • class: adatok és módszerek (method) (függvények) együttese, amely absztrakt adattípusként működik. • objektum: egy osztály egy előfordulása • módszer: az osztály egy eleme. Olyan függvény, amely az osztályba tartozó adatokon manipulál. • Üzenet (message): kommunikáció az objektummal, annakmódszerein keresztül. A C++ programozási nyelv I.
Osztálydeklaráció szintaktikája kulcsszó osztálynév <:szülők listája> { mező lista } A kulcsszó lehet: class (esetleg struct, union) Osztály definícióra használjuk MINDIG a "class" kulcsszót! Az osztály tagjai (mezői) lehetnek: • Adatmezők, adattagok (data member) • függvény-mezők, tagfüggvények (member function) A C++ programozási nyelv I.
A függvénymezők definíciója lehet • belső (ekkor inline-nak minősül) • külső (ekkor a hatáskör megjelölése szükséges) A C++ programozási nyelv I.
Hatásköri kérdések Minden osztály egy önálló osztály-hatáskört definiál. (Egységbezárás alapelve!) A meződeklarációk lokálisak az osztály-hatáskörre nézve. A tagfüggvények egy hatáskörben vannak az adattagokkal => használhatják azokat! Hatáskör: scope Egységbezárás: encapsulation A C++ programozási nyelv I.
Osztály használata Az osztálynév típusnévként viselkedik, és minden eddig ismert deklarációs konstrukcióban használható. Objektum: az osztály egy előfordulása. Például: osztály típusú változó A C++ programozási nyelv I.
Hivatkozás a tagokra Analóg a struktúrák kezelésével. Tehát: objektumnév.mező vagy objektum_pointer->mező A mező lehet • adattagra való hivatkozás (pontosan úgy, mint a struktúránál) • tagfüggvény neve és aktuális paraméter-listája A C++ programozási nyelv I.
Láthatósági kérdések Egy osztály tagjaira való hivatkozás az osztályon kívül alapértelmezés szerint tilos! (Információ rejtés alapelve!)(Information hiding) Láthatóságot szabályozó kulcsszavak: • public: a mező bárhol használható • (protected: értelmezése majd később) • private: csak az osztályon belül elérhető. Alapszabály: minden adattag private legyen! A C++ programozási nyelv I.
A kulcsszavak a meződeklarációk közé írandók, a kettősponttal együtt. A kulcsszavak hatása a másik kulcsszóig, vagy az osztály deklarációjának a végéig tart. A láthatóságot befolyásolja még a friend mechanizmus is (lásd később). A C++ programozási nyelv I.
Példa: osztálydefiníció class jarmu{ int kerekek; int szemely; int onsuly; public: void beallit(int k, int sz, int suly); double kerek_terheles (void); }; A C++ programozási nyelv I.
Példa: tagfüggvények implementációja void jarmu::beallit(int k, int sz,int suly) {kerekek = k; szemely = sz; onsuly = r;} double jarmu::kerek_terheles(void) {return (60.*szemely + onsuly)/ kerekek;} A C++ programozási nyelv I.
Példa: főprogram void main(void) { jarmu bicikli; // Objektum def. bicikli.beallit(2,1,20); printf( “Bicikli kerekterheles: %lf”, bicikli.kerek_terheles() ); } A C++ programozási nyelv I.
Objektum létrehozása Objektum létrehozása: • objektum vagy objektumtömb definíció (statikus) • newoperátor (dinamikus) • implicit létrehozás (ideiglenes objektumok) Folyamata: • helyfoglalás az adattagoknak • konstruktor automatikus meghívása A C++ programozási nyelv I.
Konstruktor Speciális tagfüggvény: • neve egyezik az osztálynévvel • nem lehet visszatérési értéke (még void sem!) • nem hívható meg közvetlenül • nem öröklődik Aktuális paraméterlista: • deklarációban az objektumnév után • new operátornál a típusnév (osztálynév) után A C++ programozási nyelv I.
Destruktor Speciális tagfüggvény: • neve ~osztálynév • nem lehet visszatérési értéke (még void sem!) • nincs paraméterlistája • nem hívható meg közvetlenül • nem öröklődik Automatikusan meghívódik egy objektum megszűnésekor. A C++ programozási nyelv I.
A this mutató Minden objektumhoz • saját adattag-készlet tartozik • az osztály összes objektumára közös a tagfüggvény-készlet. Kérdés: hogyan tud a tagfüggvény az aktuális objektum adattagjaira hivatkozni? A C++ programozási nyelv I.
Megoldás: minden objektumra létezik az előredefiniált this mutató, amely az objektum címével inicializálódik. Ezen keresztül indirekt hivatkozással éri el az adattagot a tagfüggvény. A this mutató explicite is elérhető. A C++ programozási nyelv I.
A friend mechanizmus Ha egy F külső függvény egy X osztályban "friend"-ként van deklarálva, a tagfüggvényekkel azonos elérési jogokkal rendelkezik. Az F fgv-en belül az X osztály valamenyi "private" és "protected" eleme is elérhető. Deklaráció: az X osztályban a friend kulcsszó után a függvény prototípusa. A C++ programozási nyelv I.
Példa: friend függvény class X { friend int F (int); // Dekl. int i; public: int tag (double); }; int F (int a) // Def. { . . . } A C++ programozási nyelv I.
A friend mechanizmus(folyt.) Ha az X osztályban az Y osztály "friend"-ként van deklarálva, az Y osztály összes tagfüggvénye eléri az X osztály "private" és "protected" tagjait is. Deklaráció: az X osztályban a friend class Y; sorral. A C++ programozási nyelv I.
A friend mechanizmus(folyt.) Az Y osztály egy tagfüggvénye is lehet friend az X osztályban. Deklaráció: az X osztályban a friend kulcsszó után a tagfüggvény prototípusa. A tagfüggvény neve előtt az Y:: előtag szükséges! Megjegyzések: • a friend viszony nem tranzitív • a friend viszony öröklődik A C++ programozási nyelv I.
Fordítási egységek Egy C++ programban az osztálydefiníció csak a tagfüggvények prototípusait tartalmazza, a definíciójuk külön forrásfile-ban van összegyűjtve. Szokásos megoldás: osztalynev.h Osztálydefiníció osztalynev.cpp Tagfüggvények definíciói. Hivatkozik az osztalynev.hfile-ra. A C++ programozási nyelv I.
Fordítási egységek (folyt.) Probléma: lehetséges többszörös beillesztés • újradefiniálást okozhat • fölöslegesen növeli a fordítási időt. Szokásos megoldás: egy pelda.h header file-ra #ifndef PELDA_H #define PELDA_h a header file tartalma #endif A C++ programozási nyelv I.
Operátor overloading fogalma A C++ nyelv lehetőséget nyújt arra, hogy a programozó által definiált típusokra az operátorok átértelmezhetők legyenek. A polimorfizmus implementációja! Egy operátorjel operandusainak típusa határozza meg az operátorjel jelentését. A jelentést függvénydefinícióval (tagfüggvénnyel vagy külső függvénnyel) írhatjuk le. A C++ programozási nyelv I.
Operátor overloading: alapszabályok • Minden operátor újraértelmezhető, kivéve a. .* :: ?: (feltételes) operátorokat. • Az = [] () -> new delete operátorokra speciális szabályok vonatkoznak • Az operandusok száma nem változtatható meg • Az előredefiniált típusokra vonatkozó operátorok nem definiálhatók újra. (Egy újradefiniált operátor legalább egy operandusa objektum kell legyen!) A C++ programozási nyelv I.
Alapszabályok (folyt.) • A precedencia- és asszociativitási szabályok nem változnak meg, azaz a kiértékelés sorrendje ugyanaz marad. • Az = operátor kivételével az újradefiniálás öröklődik. • Az = operátornak azonos típusú objektumokra van alapértelmezése • Nincs kommutativitás (felcserélhetőség) - a standard típusokra sem volt! A C++ programozási nyelv I.
Operátor overloading: definíció Egyoperandusú (unáris) operátor: Az x@ és @x (@ tetszőleges operátorjel) ugyanaz, és a fordítóprogram az alábbi függvényhívások valamelyikével helyettesíti: • x.operator@() ahol operator@ az x osztályának tagfüggvénye • operator@(x) az operator@ külső függvény A C++ programozási nyelv I.
Definíció (folyt.) Kétoperandusú (bináris) operátor: Az x@y kifejezést a fordítóprogram az alábbi függvényhívások valamelyikével helyettesíti: • x.operator@(y) ahol operator@ az x osztályának tagfüggvénye vagy • operator@(x,y) az operator@ külső függvény A C++ programozási nyelv I.
Kész Kész Kész Kész Egyoperandusú operátor feldolgozása Az x@ kifejezés feldolgozásának egy lehetséges forgatókönyve Feldolgozás a beépített algoritmus szerint x alaptípusú? Igen Nem x típusa Cx Cx::operator@(void) ? x@ helyettesítése az x.operator@() függvényhívással Van Nincs ::operator@(Cx x) ? x@ helyettesítése az operator@(x) függvényhívással Van Nincs Hibajelzés! A C++ programozási nyelv I.
Kétoperandusú operátor feldolgozása • Analóg az egyoperandusú esettel, az alábbi eltérésekkel: • Ha mindkét operandus alaptípusú, a beépített algorimus beépítése • Ha a baloldali operandus osztálytípusú, annak osztályában keres tagfüggvényt • Ha a baloldali operandus alaptípusú, csak a külső operátor függvények között keres A C++ programozási nyelv I.
Operátor függvény paramétereinek száma A C++ programozási nyelv I.
Operátor függvény és az operátor operandusai A C++ programozási nyelv I.
Példa: operátor overloading class complex { //comp.h double valos,kepzetes; public: complex (double v, double k); void kiir (void); complex operator+ (complex z); friend complex operator-(complex z1, complex z2); }; A C++ programozási nyelv I.
comp.cpp/1 #include <iostream.h> #include ”comp.h” complex::complex (double v, double k) // Konstruktor { valos = v; kepzetes = k; } void complex::kiir (void) { cout << "(" << valos << "," << kepzetes << ")\n"; } A C++ programozási nyelv I.
comp.cpp/2 complex complex::operator+ (complex z) // Osszeadas, tagfüggvény! {return complex(valos+z.valos, kepzetes+z.kepzetes); } A C++ programozási nyelv I.
comp.cpp/3 complex operator- (complex z1, complex z2) // Külső függvény { return complex (z1.valos-z2.valos, z1.kepzetes-z2.kepzetes); } A C++ programozási nyelv I.
proba.cpp #include ”comp.h” void main (void) { complex a(0,0), b(1,1), c(2,2); a = b + c; a.kiir(); // a = b.operator+(c) a = b - c; a.kiir(); // a = operator-(b,c) } A C++ programozási nyelv I.