dynamic binding (tsz. dynamic bindings)
virtual
) kulcsszóval van ellátva. A dinamikus névkötést főként polimorfizmus és öröklődés esetén használjuk.
Normál esetben a C++ statikus névkötést (static binding) használ, ami azt jelenti, hogy a fordító már fordítási időben eldönti, hogy egy adott függvényhívás melyik függvényre vonatkozik. Azonban polimorfikus osztályoknál szükség lehet arra, hogy a program futásidőben döntsön arról, hogy egy adott függvényhívás melyik osztály verzióját hívja meg.
#include <iostream>
using namespace std;
class Alaposztaly {
public:
void print() { // Nem virtuális függvény -> statikus névkötés
cout << "Alaposztaly print()" << endl;
}
};
class Leszarmazott : public Alaposztaly {
public:
void print() { // Nem virtuális -> statikus névkötés
cout << "Leszarmazott print()" << endl;
}
};
int main() {
Alaposztaly* obj = new Leszarmazott();
obj->print(); // Statikus névkötés miatt az Alaposztaly verziója hívódik meg
delete obj;
return 0;
}
Kimenet:
Alaposztaly print()
🔴 Hiba: Mivel a print()
függvény nem virtuális, a fordító statikus névkötést használ, és az Alaposztaly
verziója hívódik meg, annak ellenére, hogy az obj
egy Leszarmazott
objektumra mutat.
✅ Megoldás: Használjunk virtuális (virtual
) függvényeket, hogy a névkötés futásidőben történjen!
virtual
kulcsszóval)Ha egy függvény virtuális, akkor a hívás futásidőben dől el, attól függően, hogy a tényleges objektum milyen típusú.
#include <iostream>
using namespace std;
class Alaposztaly {
public:
virtual void print() { // Virtuális függvény -> dinamikus névkötés
cout << "Alaposztaly print()" << endl;
}
};
class Leszarmazott : public Alaposztaly {
public:
void print() override { // Dinamikus névkötés -> leszármazott verziója hívódik meg
cout << "Leszarmazott print()" << endl;
}
};
int main() {
Alaposztaly* obj = new Leszarmazott();
obj->print(); // Dinamikus névkötés miatt a Leszarmazott print() hívódik meg
delete obj;
return 0;
}
Kimenet:
Leszarmazott print()
✅ Miért működik? - Mivel a print()
virtuális (virtual
), a futásidőben dől el, hogy melyik osztály verziója hívódik meg. - A obj
egy Alaposztaly*
mutató, de egy Leszarmazott
objektumot mutat. - A vtable (virtuális táblázat) mechanizmusnak köszönhetően a megfelelő verzió (Leszarmazott::print()
) fut le.
A dinamikus névkötés a virtuális táblázaton (vtable) és a virtuális mutatón (vptr) alapul.
#include <iostream>
using namespace std;
class Alaposztaly {
public:
virtual void f1() { cout << "Alaposztaly f1" << endl; }
virtual void f2() { cout << "Alaposztaly f2" << endl; }
};
class Leszarmazott : public Alaposztaly {
public:
void f1() override { cout << "Leszarmazott f1" << endl; } // Felülírva
void f2() override { cout << "Leszarmazott f2" << endl; } // Felülírva
};
int main() {
Alaposztaly* obj = new Leszarmazott();
obj->f1(); // Leszarmazott f1
obj->f2(); // Leszarmazott f2
delete obj;
return 0;
}
✅ A futásidőben dől el, hogy a Leszarmazott
osztály függvényei hívódnak meg.
Ha egy osztály virtuális függvényeket tartalmaz, a destruktora is legyen virtuális, különben memória-szivárgás történhet!
#include <iostream>
using namespace std;
class Alaposztaly {
public:
virtual ~Alaposztaly() { cout << "Alaposztaly destruktor" << endl; }
};
class Leszarmazott : public Alaposztaly {
public:
~Leszarmazott() { cout << "Leszarmazott destruktor" << endl; }
};
int main() {
Alaposztaly* obj = new Leszarmazott();
delete obj; // Helyesen hívja a Leszarmazott destruktorát
return 0;
}
Kimenet:
Leszarmazott destruktor Alaposztaly destruktor
✅ A ~Alaposztaly()
virtuális, így a megfelelő destruktorok meghívódnak.
Típus | Időpont | Használat | Példa |
---|---|---|---|
Statikus névkötés (Static Binding) | Fordítási időben | Normál függvények, statikus változók | Nem virtuális osztályfüggvények |
Dinamikus névkötés (Dynamic Binding) | Futási időben | Virtuális függvények, polimorfizmus | Virtuális függvények (virtual )
|
✅ A dinamikus névkötés (dynamic binding
) azt jelenti, hogy a függvényhívás futásidőben dől el.
✅ Virtuális (virtual
) függvények használatával érhető el.
✅ A polimorfizmus megvalósításához elengedhetetlen.
✅ A virtuális táblázat (vtable) és virtuális mutató (vptr) mechanizmuson alapul.