function overriding
Főnév
function overriding (tsz. function overridings)
- (informatika) A függvény felüldefiniálás (method/function overriding) egy olyan objektumorientált programozási (OOP) technika C++-ban, amely lehetővé teszi, hogy egy leszármazott osztály újradefiniálja egy szülőosztály metódusát. Ezáltal a gyermekosztály módosíthatja vagy kibővítheti az alaposztály viselkedését.
1. Mi az a metódus felüldefiniálás?
A metódus felüldefiniálás azt jelenti, hogy egy származtatott (leszármazott) osztályban egy már létező függvényt újraimplementálunk.
Feltételek: 1. Ugyanolyan névvel kell rendelkeznie, mint a szülőosztály függvénye. 2. Ugyanolyan paraméterlistával kell rendelkeznie (különben metódus túlterhelés történik, nem felüldefiniálás). 3. A szülőosztályban a függvénynek virtual-ként kell szerepelnie, hogy dinamikus kötést lehessen alkalmazni.
2. Egyszerű példa metódus felüldefiniálásra
#include <iostream>
using namespace std;
class Alap {
public:
virtual void koszont() { // A `virtual` lehetővé teszi a felüldefiniálást
cout << "Üdvözöllek az Alap osztályból!" << endl;
}
};
class Szarmaztatott : public Alap {
public:
void koszont() override { // Felüldefiniálás
cout << "Helló a Származtatott osztályból!" << endl;
}
};
int main() {
Alap* obj = new Szarmaztatott(); // Alaposztály pointere mutat a leszármazott objektumra
obj->koszont(); // A leszármazott osztály metódusa hívódik meg (dinamikus kötés)
delete obj;
return 0;
}
Kimenet:
Helló a Származtatott osztályból!
Mi történik itt? 1. Az Alap osztályban van egy virtual void koszont() függvény. 2. A Szarmaztatott osztályban ezt újraimplementáljuk. 3. A polimorfizmus miatt a megfelelő függvény fut le a futásidőben (runtime), nem pedig fordítási időben.
3. Miért fontos a virtual kulcsszó?
Ha az Alap osztályban nem lenne virtual, akkor a statikus kötés miatt mindig az alaposztály metódusa hívódna meg, függetlenül attól, hogy valójában milyen típusú objektumot használunk.
Példa virtual nélkül:
class Alap {
public:
void koszont() { // NINCS `virtual`
cout << "Üdvözöllek az Alap osztályból!" << endl;
}
};
class Szarmaztatott : public Alap {
public:
void koszont() {
cout << "Helló a Származtatott osztályból!" << endl;
}
};
int main() {
Alap* obj = new Szarmaztatott();
obj->koszont(); // A szülőosztály függvénye hívódik meg!
delete obj;
return 0;
}
Kimenet:
Üdvözöllek az Alap osztályból!
Mivel a koszont() nincs virtual-ként megjelölve, az alaposztály függvénye hívódik meg még akkor is, ha az objektum valójában a Szarmaztatott osztályból származik.
Ezért szükséges a virtual használata, hogy a helyes metódus fusson le futásidőben.
4. override és final kulcsszavak
C++11-től két kulcsszó is használható a felüldefiniálásnál:
4.1 override – Segít az egyértelműségben
A override kulcsszó jelzi, hogy egy függvény felülír egy szülőbeli metódust.
class Alap {
public:
virtual void koszont() {
cout << "Alap osztály" << endl;
}
};
class Szarmaztatott : public Alap {
public:
void koszont() override { // `override` jelzi, hogy ez felüldefiniálás
cout << "Szarmaztatott osztály" << endl;
}
};
Ha a override kulcsszó jelen van, és rossz szignatúrával próbálunk felüldefiniálni egy metódust, akkor a fordító hibát jelez.
4.2 final – Megakadályozza a további felüldefiniálást
A final kulcsszóval megtilthatjuk a további felüldefiniálást.
class Alap {
public:
virtual void koszont() final { // Ezt már nem lehet felüldefiniálni!
cout << "Alap osztály" << endl;
}
};
class Szarmaztatott : public Alap {
public:
// void koszont() override { // Fordítási hiba! Mert `final`
// cout << "Szarmaztatott osztály" << endl;
// }
};
Ha egy osztályt final-ként jelölünk (class Szarmaztatott final), akkor abból nem lehet leszármaztatni új osztályokat.
5. Konstruktorok és metódus felüldefiniálás
A konstruktorok nem lehetnek virtuálisak, viszont a destruktoroknak virtuálisnak kell lenniük az örökölt objektumok helyes törlése érdekében.
class Alap {
public:
virtual ~Alap() { // Virtuális destruktor biztosítja a helyes felszabadítást
cout << "Alap destruktor" << endl;
}
};
class Szarmaztatott : public Alap {
public:
~Szarmaztatott() {
cout << "Szarmaztatott destruktor" << endl;
}
};
int main() {
Alap* obj = new Szarmaztatott();
delete obj; // Helyesen mindkét destruktor lefut!
return 0;
}
Kimenet:
Szarmaztatott destruktor Alap destruktor
Ha a ~Alap() nem lenne virtuális, akkor csak az alaposztály destruktora hívódna meg, és memóriaszivárgás történhetne.
6. Összegzés
| Tulajdonság | Magyarázat |
|---|---|
Felüldefiniálás (override) |
A leszármazott osztály újraimplementálja a szülő metódusát. |
virtual kulcsszó |
Az alaposztály metódusa virtuális kell legyen a helyes működéshez. |
| Statikus vs. dinamikus kötés | Virtuális nélkül statikus kötés van (fordítási időben dől el), virtuálissal dinamikus kötés történik (futásidőben). |
override |
Fordítási hibát ad, ha nincs pontos egyezés a szülő metódussal. |
final |
Megakadályozza a további felüldefiniálást. |
| Virtuális destruktor | Megakadályozza a memóriaszivárgást az öröklődő objektumok törlésekor. |
Konklúzió
A metódus felüldefiniálás egy alapvető OOP technika C++-ban, amely lehetővé teszi a polimorfizmus és a dinamikus kötés használatát. Ha az öröklődést helyesen kezeljük virtuális függvényekkel és destruktorokkal, akkor rugalmasabb és karbantarthatóbb kódot kapunk.
- function overriding - Szótár.net (en-hu)
- function overriding - Sztaki (en-hu)
- function overriding - Merriam–Webster
- function overriding - Cambridge
- function overriding - WordNet
- function overriding - Яндекс (en-ru)
- function overriding - Google (en-hu)
- function overriding - Wikidata
- function overriding - Wikipédia (angol)