Származtatási mechanizmus a C++ nyelvben Miskolci Egyetem Általános Informatikai Tanszék CPP2 / 1 Az öröklődés s fogalma 1. Egy osztály deklarálható valamely más osztály(ok) leszármazottjaként. Az deklaráció formája: class név: [kulcsszo] osztalynev1 [, [kulcsszo] osztalynev2... ] { // itt jön a tagok deklarációja } Öröklődés: inheritance A C++ programozási nyelv 2. (Öröklődés) CPP2 / 2 Az öröklődés s fogalma 2. A kulcsszo (amely az öröklés módját írja elő) lehet public vagy private Ha a kulcsszo hiányzik, az alapértelmezés private (információ rejtés alapelve!) Azosztálynev1 nevű osztály a szülő, vagy ős osztály. (base class) A C++ programozási nyelv 2. (Öröklődés) CPP2 / 3
Az öröklődés s fogalma 3. A név osztály rendelkezik a szülő osztály tagjaival a saját tagjaival Az ős osztály elemeinek az elérése a leszármazott osztályból nem feltétlenül garantált. Öröklődnek bizonyos tulajdonságok. Pl. operátor overloading friend függvények és osztályok A C++ programozási nyelv 2. (Öröklődés) CPP2 / 4 Az öröklődés s fogalma 4. Az öröklődési hierarchia tetszőleges lehet. Egyetlen korlátozás: egy osztály még közvetett módon sem lehet saját maga őse. Az ős osztály továbbra is használható önmagában is. A C++ programozási nyelv 2. (Öröklődés) CPP2 / 5 Egyszerű példa: CPPEX6.CPP Az egyszerű hierarchiára példa a CPPEX6.CPP Ez szemlélteti: akkor érdemes használni, ha a modellezendő valóságos objektumok viszonya is hierarchikus az öröklést tartalmazó definíciót azonos nevű függvények a különböző szinteken. Ez újradeklarálás, nem pedig függvény overloading. (SCOPE operátor használata!) a public öröklési módot A C++ programozási nyelv 2. (Öröklődés) CPP2 / 6
Egyszerű példa: jarmu osztály class jarmu { // public oroklesi mod int kerekek; double suly; void kezdoertek(int k, double s) {kerekek = k; suly = s;} int kerekszam (void) { return kerekek;} double kerekterheles(void) {return suly / kerekek; double sulya() {return suly;} A C++ programozási nyelv 2. (Öröklődés) CPP2 / 7 Egyszerű példa: gepkocsi osztály class gepkocsi : public jarmu { void kezdoertek(int k, double s, int szem) {szemelyek = szem; jarmu::kezdoertek(k, s); } A C++ programozási nyelv 2. (Öröklődés) CPP2 / 8 Egyszerű példa: teherauto osztály class teherauto : public jarmu { double raksuly; void teher_kezdoertek (int szem,double rs) {szemelyek = szem; raksuly = rs; } double kerekterheles() {return (sulya() + raksuly + szemelyek*60.) / kerekszam(); } // suly + hibas lenne, mert suly // nem elérhető!!! A C++ programozási nyelv 2. (Öröklődés) CPP2 / 9
Egyszerű példa: bicikli objektum main () { jarmu bicikli; bicikli.kezdoertek(2,15.0); cout << "Bicikli kerekeinek szama " << bicikli.kerekszam() << "\n"; cout << "Bicikli kerekterhelese: " << bicikli.kerekterheles() << "\n"; A C++ programozási nyelv 2. (Öröklődés) CPP2 / 10 A bicikli objektum felépítése Az objektum típusa jarmu kerekek súly class jarmu A C++ programozási nyelv 2. (Öröklődés) CPP2 / 11 Egyszerű példa: trabant objektum gepkocsi trabant; trabant.kezdoertek (4, 600.0, 4); cout << "Trabant kerekeinek szama: " << trabant.kerekszam() << "\n"; A C++ programozási nyelv 2. (Öröklődés) CPP2 / 12
A trabant objektum felépítése Az objektum gepkocsi típusú kerekek súly szemelyek class jarmu Gepkocsi sajat adattagja class gepkocsi A C++ programozási nyelv 2. (Öröklődés) CPP2 / 13 Egyszerű példa: ifa objektum teherauto ifa; ifa.kezdoertek(6, 1200.0); ifa.teher_kezdoertek(2,2500.0); cout << "Max. kerekterheles: " << ifa.kerekterheles() << "\n"; } A C++ programozási nyelv 2. (Öröklődés) CPP2 / 14 Eredmény: Egyszerű példa: eredmény Bicikli kerekeinek szama: 2 Bicikli kerekterhelese: 7.5 Trabant kerekeinek szama: 4 Max. kerekterheles: 636.667 A C++ programozási nyelv 2. (Öröklődés) CPP2 / 15
Láthatósági kulcsszavak Egy osztály mezőinek láthatósága lehet: a mező bárhol használható, ahol az osztály ismert protected: a mező az adott osztály és annak valamennyi leszármazott osztálya számára ismert private: a mező csak az adott osztály számára ismert Az öröklés módja ezek hatását módosíthatja a leszármazott osztályok számára! A C++ programozási nyelv 2. (Öröklődés) CPP2 / 16 Öröklés módja public private Láthatóság és öröklődés 1. Láthatóság (ős) public protected private public protected private Láthatóság (leszármazott) public protected nem elérhető private private nem elérhető A C++ programozási nyelv 2. (Öröklődés) CPP2 / 17 Láthatóság és öröklődés 2. Megjegyzések: Az öröklés módja csak korlátozhatja a hatáskört. Egy leszármazott osztály elérési joga kisebb, mind a friend osztályé. Példák: CPPEX7.C és CPPEX8.C A kulsofgv használhatja a c,e és Xfgv tagokat. Az Xfgv használhatja a b,c,d,e és Bfgv tagokat. A C++ programozási nyelv 2. (Öröklődés) CPP2 / 18
Példa a private öröklési módra (cppex6a) class jarmu { int kerekek; double suly; void kezdoertek(int k, double s) {kerekek = k; suly = s;} int hanykerek (void) { return kerekek;} double kerekterheles(void) {return suly / kerekek; double sulya(void) {return suly;} A C++ programozási nyelv 2. (Öröklődés) CPP2 / 19 Példa a private öröklési módra (cppex6a) class gepkocsi : jarmu {//alapért: private void kezdoertek(int k, double s, int szem) { szemelyek = szem; jarmu::kezdoertek(k, s); } A C++ programozási nyelv 2. (Öröklődés) CPP2 / 20 Példa a private öröklési módra (cppex6a) main () { gepkocsi trabant; trabant.kezdoertek (4, 600.0, 4); // double jarmu::sulya() is inaccessible // within this context Cout << "Trabant sulya:" << trabant.sulya() << "\n"; // Az örökölt sulya fgv. private // láthatóságú! } A C++ programozási nyelv 2. (Öröklődés) CPP2 / 21
Megoldás wrapper függvénnyel (cppex6b) class jarmu { // ugyanaz, mint előbb class gepkocsi : jarmu { void kezdoertek(int k, double s, int szem) {// Ugyanaz, mint előbb } // Ez a wrapper fuggveny double sulya(void) { return jarmu::sulya();} A C++ programozási nyelv 2. (Öröklődés) CPP2 / 22 Megoldás explicit átminá tminősítésselssel (cppex6c) class jarmu { // ugyanaz, mint előbb class gepkocsi : jarmu { void kezdoertek(int k, double s, int szem) {// Ugyanaz, mint előbb } // A sulya fgv-t explicite public-a // tesszuk jarmu::sulya; A C++ programozási nyelv 2. (Öröklődés) CPP2 / 23 Konstruktorok és s destruktorok 1. Egy leszármaztatott objektum létrehozásakor először a szülő osztály(ok) konstruktora(i) hajtódnak végre (a deklaráció sorrendjében), majd a leszármaztatott osztályé. A leszármazott osztály konstruktora kijelölheti az ősosztály megfelelő konstruktorát a definíciójában megadott taginicializációs listával. (Formáját lásd a példában) További szabályok is vannak. A C++ programozási nyelv 2. (Öröklődés) CPP2 / 24
Konstruktorok és s destruktorok 2. A destruktorok végrehajtási sorrendje most is pontosan fordítottja a konstruktorénak. Egyszerű példa: CPPEX11.C A C++ programozási nyelv 2. (Öröklődés) CPP2 / 25 cppex11.c 1. class jarmu { protected: int kerekek; double suly; jarmu (int k, double s) {kerekek = k; suly = s;} int hanykerek(void {return kerekek;} A C++ programozási nyelv 2. (Öröklődés) CPP2 / 26 cppex11.c 2. class gepkocsi : public jarmu { protected: gepkocsi(int k,double s,int szem) : jarmu (k, s) {szemelyek = szem;} A C++ programozási nyelv 2. (Öröklődés) CPP2 / 27
cppex11.c 3. main () { jarmu bicikli (2,15); cout<< "Bicikli kerekeinek szama: " << bicikli.hanykerek() << "\n"; gepkocsi trabant (4, 120.0, 4); cout<< "Trabant kerekeinek szama: " << trabant.hanykerek() << "\n"; } A C++ programozási nyelv 2. (Öröklődés) CPP2 / 28