virtual destructor
Főnév
virtual destructor (tsz. virtual destructors)
- (informatika) A virtuális destruktor (virtual destructor) egy speciális destruktor C++-ban, amely biztosítja, hogy a helyes destruktor hívódjon meg öröklődés esetén. Ha egy osztály nem rendelkezik virtuális destruktorral, akkor polimorfikus használat esetén memóriaszivárgás történhet, mivel a leszármazott osztály destruktora nem hívódik meg.
1. Mi az a destruktor?
Egy destruktor egy olyan speciális függvény egy osztályban, amely akkor fut le, amikor egy objektum megsemmisül (például amikor meghívjuk a delete operátort egy dinamikusan létrehozott objektumra).
Szintaxisa:
class Osztaly {
public:
~Osztaly() {
// Destruktor kódja
}
};
2. Miért van szükség virtuális destruktorra?
Amikor egy objektumot egy alaposztály mutatóján keresztül törlünk, a helyes destruktor fut le vagy nem attól függően, hogy az alaposztály destruktora virtuális vagy nem.
Ha a destruktor nem virtuális, akkor csak az alaposztály destruktora fut le, és a származtatott osztály erőforrásai nem szabadulnak fel, ami memóriaszivárgáshoz vezethet.
3. Probléma virtuális destruktor nélkül
Példa: Memóriaszivárgás történik, ha nincs virtuális destruktor
#include <iostream>
using namespace std;
class Alap {
public:
~Alap() {
cout << "Alap destruktor" << endl;
}
};
class Szarmaztatott : public Alap {
public:
~Szarmaztatott() {
cout << "Szarmaztatott destruktor" << endl;
}
};
int main() {
Alap* obj = new Szarmaztatott(); // Alap osztály mutatója mutat egy Szarmaztatott objektumra
delete obj; // Csak az Alap destruktora hívódik meg!
return 0;
}
Kimenet:
Alap destruktor
Probléma: - Az Szarmaztatott destruktora nem hívódik meg, így ha tartalmaz dinamikusan foglalt memóriát, az soha nem kerül felszabadításra (memóriaszivárgás!).
4. Megoldás: Virtuális Destruktor
Ha az alaposztály destruktora virtuális, akkor a C++ biztosítja, hogy a leszármazott osztály destruktora is meghívódjon.
Helyes megoldás: Virtuális destruktor használata
#include <iostream>
using namespace std;
class Alap {
public:
virtual ~Alap() { // Virtuális destruktor
cout << "Alap destruktor" << endl;
}
};
class Szarmaztatott : public Alap {
public:
~Szarmaztatott() {
cout << "Szarmaztatott destruktor" << endl;
}
};
int main() {
Alap* obj = new Szarmaztatott();
delete obj; // Most mindkét destruktor lefut!
return 0;
}
Kimenet:
Szarmaztatott destruktor Alap destruktor
Mi történik itt?
- Az
Alapdestruktora virtuális, így a C++ dinamikus kötést használ. - Először a
Szarmaztatottdestruktora fut le, ami felszabadítja aSzarmaztatotterőforrásait. - Ezután az
Alapdestruktora hívódik meg. - Nincs memóriaszivárgás, minden erőforrás felszabadul.
5. Mikor kell virtuális destruktort használni?
Virtuális destruktorra van szükség, ha: ✅ Az osztály öröklődhet más osztályok által.
✅ Az osztály példányait alaposztály mutatóin keresztül is törölhetjük.
✅ Az osztály vagy a leszármazottak dinamikus memóriát használnak (new).
Virtuális destruktorok használatának szabályai
| Helyzet | Virtuális destruktor szükséges? | Miért? |
|---|---|---|
| Nincs öröklés | ❌ Nem kell | Nincs polimorfizmus |
Öröklés, de soha nem használunk delete-et az alaposztály mutatóján keresztül |
❌ Nem kell | Nincs polimorf törlés |
Öröklés, és delete-et használunk alaposztály mutatóval |
✅ Igen kell | Megakadályozza a memóriaszivárgást |
6. virtual destruktor és teljesítmény
A virtuális destruktoroknak van egy kis költsége, mert a C++ virtuális táblát (vtable) hoz létre, hogy a helyes destruktort hívja meg futásidőben.
Ez ritkán jelent problémát, de ha egy osztály soha nem lesz örökölt, akkor felesleges a virtual destruktor.
7. override és final virtuális destruktorokkal
C++11-től két új kulcsszóval javíthatjuk a destruktorokat:
override a pontos felüldefiniálásért
class Alap {
public:
virtual ~Alap() {}
};
class Szarmaztatott : public Alap {
public:
~Szarmaztatott() override {} // A fordító ellenőrzi, hogy tényleg felüldefiniáljuk
};
- Ha nincs
virtualaz alaposztályban, a fordító hibát ad. - Biztonságosabb, mert segít az elírások ellenőrzésében.
final a további öröklés megakadályozására
class Alap {
public:
virtual ~Alap() final {} // Ezt már nem lehet tovább felüldefiniálni
};
class Szarmaztatott : public Alap {
public:
// ~Szarmaztatott() override {} // Fordítási hiba! Mert `final`-ként van jelölve
};
- Ha egy destruktor
final-ként van jelölve, nem lehet felüldefiniálni.
8. Összegzés
| Fogalom | Leírás | Példa |
|---|---|---|
| Nem virtuális destruktor | Csak az alaposztály destruktora fut le | ~Alap() {} |
| Virtuális destruktor | A leszármazott osztály destruktora is meghívódik | virtual ~Alap() {} |
override destruktorral |
Ellenőrzi, hogy a destruktor valóban felül van-e definiálva | ~Szarmaztatott() override {} |
final destruktorral |
Megakadályozza, hogy a destruktort később felüldefiniáljuk | virtual ~Alap() final {} |
9. Konklúzió
A virtuális destruktor biztosítja, hogy öröklődés esetén az objektumok helyesen törlődjenek, és ne legyen memóriaszivárgás.
Ha egy osztályt polimorf módon használunk, és az lehetőséget biztosít öröklődésre, akkor mindig virtuális destruktort kell használnunk.
- virtual destructor - Szótár.net (en-hu)
- virtual destructor - Sztaki (en-hu)
- virtual destructor - Merriam–Webster
- virtual destructor - Cambridge
- virtual destructor - WordNet
- virtual destructor - Яндекс (en-ru)
- virtual destructor - Google (en-hu)
- virtual destructor - Wikidata
- virtual destructor - Wikipédia (angol)