Virtual Functions
Jab Base class pointer/reference se Derived class object access karte ho, normally Base ka version hi call hota hai (static binding) — chahe object actually Derived ho. virtual keyword se ye badal jaata hai: sahi (Derived) version call hota hai, runtime par decide hota hai — isse "runtime polymorphism" kehte hain.
Ye C++ ki OOP ka sabse powerful feature hai — ek hi Base pointer se, alag-alag Derived types ka sahi behavior mil sakta hai, bina explicit type-checking (if-else) ke.
class Animal {
public:
virtual void makeSound() { cout << "..." << endl; } // virtual!
};
class Dog : public Animal {
public:
void makeSound() override { cout << "Bhow!" << endl; }
};
class Cat : public Animal {
public:
void makeSound() override { cout << "Meow!" << endl; }
};
int main() {
Animal *animals[2];
animals[0] = new Dog();
animals[1] = new Cat();
for (int i = 0; i < 2; i++) {
animals[i]->makeSound(); // sahi version chalega: "Bhow!" phir "Meow!"
}
return 0;
}- virtual = runtime par sahi version decide hota hai (dynamic binding)
- Base pointer/reference se Derived ka sahi behavior milta hai
- override keyword se typos compile-time par pakde jaate hain
Internally, virtual functions ek "vtable" (virtual function table) use karte hain — har class jiske paas virtual functions hain, ek hidden table rakhti hai jo sahi function ke address point karti hai. Runtime par, object ke vtable ke through sahi function call hota hai — isi wajah se virtual functions ka thoda extra runtime overhead hota hai (negligible zyadatar cases mein).
// Conceptually (compiler internally generate karta hai):
// Dog object → vtable → makeSound() ka Dog::makeSound address
// Ye overhead hai isliye HAR function virtual nahi banaya jaata —
// sirf jaha polymorphism genuinely chahiye