osztály és objektum fogalma -...
TRANSCRIPT
FicsorLajos
A C++ programozási nyelv I. CPP1/ 2
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, annak módszerein keresztül.
FicsorLajos
A C++ programozási nyelv I. CPP1/ 3
Osztálydeklaráció szintaktikájakulcsszó 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)
FicsorLajos
A C++ programozási nyelv I. CPP1/ 4
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)
FicsorLajos
A C++ programozási nyelv I. CPP1/ 5
Hatásköri kérdésekMinden 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: scopeEgységbezárás: encapsulation
FicsorLajos
A C++ programozási nyelv I. CPP1/ 6
Osztály használataAz 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ó
FicsorLajos
A C++ programozási nyelv I. CPP1/ 7
Hivatkozás a tagokraAnaló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
FicsorLajos
A C++ programozási nyelv I. CPP1/ 8
Láthatósági kérdésekEgy 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!
FicsorLajos
A C++ programozási nyelv I. CPP1/ 9
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 friendmechanizmus is (lásd később).
FicsorLajos
A C++ programozási nyelv I. CPP1/ 10
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);
};
FicsorLajos
A C++ programozási nyelv I. CPP1/ 11
Példa: tagfüggvények implementációjavoid jarmu::beallit(int k,intsz,int suly)
{kerekek = k; szemely = sz;onsuly = r;}
double jarmu::kerek_terheles(void)
{return (60.*szemely + onsuly)/kerekek;}
FicsorLajos
A C++ programozási nyelv I. CPP1/ 12
Példa: főprogramvoid main(void){jarmu bicikli; // Objektum def.bicikli.beallit(2,1,20);printf(“Bicikli kerekterheles: %lf”,bicikli.kerek_terheles() );}
FicsorLajos
A C++ programozási nyelv I. CPP1/ 13
Objektum létrehozásaObjektum létrehozása:• objektum vagy objektumtömb definíció
(statikus)• new operátor (dinamikus)• implicit létrehozás (ideiglenes objektumok)Folyamata:• helyfoglalás az adattagoknak• konstruktor automatikus meghívása
FicsorLajos
A C++ programozási nyelv I. CPP1/ 14
KonstruktorSpeciá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ődikAktuális paraméterlista:• deklarációban az objektumnév után• new operátornál a típusnév (osztálynév) után
FicsorLajos
A C++ programozási nyelv I. CPP1/ 15
DestruktorSpeciá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ődikAutomatikusan meghívódik egy objektum
megszűnésekor.
FicsorLajos
A C++ programozási nyelv I. CPP1/ 16
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?
FicsorLajos
A C++ programozási nyelv I. CPP1/ 17
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ő.
FicsorLajos
A C++ programozási nyelv I. CPP1/ 18
A friend mechanizmusHa 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.
FicsorLajos
A C++ programozási nyelv I. CPP1/ 19
Példa: friend függvényclass X {friend int F (int); // Dekl.int i;public:int tag (double);};int F (int a) // Def.{ . . . }
FicsorLajos
A C++ programozási nyelv I. CPP1/ 20
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 afriend class Y;
sorral.
FicsorLajos
A C++ programozási nyelv I. CPP1/ 21
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 friendkulcsszó 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
FicsorLajos
A C++ programozási nyelv I. CPP1/ 22
Fordítási egységekEgy 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.
FicsorLajos
A C++ programozási nyelv I. CPP1/ 23
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
FicsorLajos
A C++ programozási nyelv I. CPP1/ 24
Operátor overloading fogalmaA 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.
FicsorLajos
A C++ programozási nyelv I. CPP1/ 25
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 operandusaobjektum kell legyen!)
FicsorLajos
A C++ programozási nyelv I. CPP1/ 26
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!
FicsorLajos
A C++ programozási nyelv I. CPP1/ 27
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
FicsorLajos
A C++ programozási nyelv I. CPP1/ 28
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ényevagy• operator@(x,y)az operator@ külső függvény
FicsorLajos
A C++ programozási nyelv I. CPP1/ 29
Egyoperandusú operátor feldolgozásaAz x@ kifejezés feldolgozásának egy lehetséges forgatókönyve
x alaptípusú? IgenFeldolgozás a beépítettalgoritmus szerint
Kész
Nem
x típusa Cx
x@ helyettesítése azx.operator@()függvényhívással
KészVan
Cx::operator@(void) ?
Nincs
x@ helyettesítése azoperator@(x)függvényhívással
KészVan::operator@(Cx x) ?
NincsHibajelzés! Kész
FicsorLajos
A C++ programozási nyelv I. CPP1/ 30
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
FicsorLajos
A C++ programozási nyelv I. CPP1/ 31
Operátor függvény paramétereinek száma
21Az operátor definiáló függvény külső függvény
10Az operátor definiáló függvény tagfüggvény
Kétoperandusúoperátor
Egyoperandusúoperátor
FicsorLajos
A C++ programozási nyelv I. CPP1/ 32
Operátor függvény és az operátoroperandusai
Baloldali: a függvény első paramétereJobboldali: a függvény második paramétere
A függvény aktuális paramétere
Az operátor definiáló függvény külső függvény
Baloldali: az aktuális objektumJobboldali: a függvény paramétere
Az aktuális objektum
Az operátor definiáló függvény tagfüggvény
Kétoperandusúoperátor
Egyoperan-dusú operátor
FicsorLajos
A C++ programozási nyelv I. CPP1/ 33
Példa: operátor overloadingclass complex { //comp.hdouble valos,kepzetes;
public:complex (double v, double k);void kiir (void);complex operator+ (complex z);friend complex operator-;
};
FicsorLajos
A C++ programozási nyelv I. CPP1/ 34
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"; }
FicsorLajos
A C++ programozási nyelv I. CPP1/ 35
comp.cpp/2complex complex::operator+ (complex z)
// Osszeadas, tagfüggvény!{return complex(valos+z.valos,kepzetes+z.kepzetes); }
FicsorLajos
A C++ programozási nyelv I. CPP1/ 36
comp.cpp/3complex operator- (complex z1,
complex z2)// Külső függvény{returncomplex (z1.valos-z2.valos,
z1.kepzetes-z2.kepzetes);}