Free tutorials & notes in Hindi & English · Clean code examples · Mobile friendly learning
Free tutorials in Hindi & English Daily computer, mobile and IT guides Beginner friendly learning
Blog · C++ · 04 Jul 2026 · Hindi + English

C++ में Virtual Function: क्यों होता है, आसान Example के साथ

Virtual के बिना base pointer child object के लिए भी base version call करता है. virtual call को runtime पर actual object से decide करवाता है. Before/after proof.

First, feel the problem (without virtual)

Virtual functions solve one specific problem. To understand them, you must first see the problem. Here it is:
#include <iostream>
using namespace std;

class Animal {
public:
    void sound() { cout << "Some generic sound\n"; }   // NOT virtual
};

class Dog : public Animal {
public:
    void sound() { cout << "Bark!\n"; }
};

int main() {
    Animal *a = new Dog();     // base pointer, but Dog object!
    a->sound();                 // which version runs?
    delete a;
    return 0;
}
Some generic sound

Wrong answer came out! The object is a Dog, but "Some generic sound" printed. Why? Without virtual, the compiler decides the call by looking at the pointer's type (Animal*) at compile time. It never looks at the actual object. This is called early binding.

Now add one word — virtual

class Animal {
public:
    virtual void sound() { cout << "Some generic sound\n"; }  // virtual!
};

class Dog : public Animal {
public:
    void sound() override { cout << "Bark!\n"; }
};

int main() {
    Animal *a = new Dog();
    a->sound();                 // now?
    delete a;
    return 0;
}
Bark!

Correct! The word virtual tells the compiler: "don't decide now — wait until the program runs and look at the actual object". This is late binding / runtime polymorphism. Internally, the compiler builds a hidden table of function addresses (the vtable) and each object carries a pointer to its class's table — that is how the right version is found at runtime.

Why this matters in real code

void morningRoutine(Animal *a) {     // works for ANY animal -
    a->sound();                       // even ones written NEXT YEAR
}

Dog d; Cat c; Cow w;
morningRoutine(&d);    // Bark!
morningRoutine(&c);    // Meow!
morningRoutine(&w);    // Moo!
Bark! Meow! Moo!

One function handles every present and future animal type without modification. Every plugin system, every GUI framework, every game engine runs on exactly this mechanism.

The virtual destructor rule (senior-level question)

Animal *a = new Dog();
delete a;      // if ~Animal() is NOT virtual:
               // only Animal's destructor runs, Dog's part leaks!
Rule: if a class has any virtual function, its destructor should also be virtual. Otherwise deleting a child object through a base pointer destroys only the base part — Dog's resources leak. One line fixes it: virtual ~Animal() { }.

Summary table

PointNormal functionVirtual function
Call decidedCompile time (early binding)Runtime (late binding)
Decided byPointer/reference typeActual object type
MechanismDirect callvtable lookup
EnablesRuntime polymorphism
CostNoneTiny (one pointer lookup)

पहले problem को महसूस करें (बिना virtual के)

Virtual functions एक specific problem solve करते हैं. समझने के लिए पहले problem को देखना ज़रूरी है. यह रही:
#include <iostream>
using namespace std;

class Animal {
public:
    void sound() { cout << "Some generic sound\n"; }   // virtual NAHI
};

class Dog : public Animal {
public:
    void sound() { cout << "Bark!\n"; }
};

int main() {
    Animal *a = new Dog();     // base pointer, लेकिन Dog object!
    a->sound();                 // कौन-सा version चलेगा?
    delete a;
    return 0;
}
Some generic sound

गलत answer निकला! Object Dog है, लेकिन "Some generic sound" print हुआ. क्यों? Virtual के बिना compiler call को compile time पर pointer के type (Animal*) से decide करता है. असली object को देखता ही नहीं. इसे early binding कहते हैं.

अब सिर्फ एक शब्द जोड़ें — virtual

class Animal {
public:
    virtual void sound() { cout << "Some generic sound\n"; }  // virtual!
};

class Dog : public Animal {
public:
    void sound() override { cout << "Bark!\n"; }
};

int main() {
    Animal *a = new Dog();
    a->sound();                 // अब?
    delete a;
    return 0;
}
Bark!

सही! virtual शब्द compiler से कहता है: "अभी decide मत करो — program चलने तक रुको और असली object देखो". यही late binding / runtime polymorphism है. अंदर से compiler function addresses की एक hidden table (vtable) बनाता है और हर object अपनी class की table का pointer साथ रखता है — runtime पर सही version ऐसे मिलता है.

Real code में यह क्यों matter करता है

void morningRoutine(Animal *a) {     // HAR animal के लिए चलता है -
    a->sound();                       // अगले साल लिखे जाने वालों के लिए भी
}

Dog d; Cat c; Cow w;
morningRoutine(&d);    // Bark!
morningRoutine(&c);    // Meow!
morningRoutine(&w);    // Moo!
Bark! Meow! Moo!

एक function हर मौजूदा और आने वाले animal type को बिना बदलाव के handle करता है. हर plugin system, हर GUI framework, हर game engine इसी mechanism पर चलता है.

Virtual destructor rule (senior-level question)

Animal *a = new Dog();
delete a;      // अगर ~Animal() virtual NAHI है:
               // सिर्फ Animal का destructor चलेगा, Dog का हिस्सा leak!
Rule: अगर class में कोई भी virtual function है, तो destructor भी virtual होना चाहिए. वरना base pointer से child object delete करने पर सिर्फ base हिस्सा destroy होता है — Dog के resources leak हो जाते हैं. एक line से fix: virtual ~Animal() { }.

Summary table

PointNormal functionVirtual function
Call decideCompile time (early binding)Runtime (late binding)
Decide करता हैPointer/reference का typeअसली object का type
MechanismDirect callvtable lookup
Enable करता हैRuntime polymorphism
Costकुछ नहींबहुत छोटी (एक pointer lookup)

Frequently Asked Questions

Virtual function आसान शब्दों में क्या है?

Virtual function compiler से कहता है कि कौन-सा version call होगा यह runtime पर असली object देखकर decide हो, compile time पर pointer type देखकर नहीं — इसी से runtime polymorphism मिलती है.

vtable क्या है?

Virtual function addresses की hidden table जो compiler हर class के लिए बनाता है; हर object अपनी class की vtable का pointer रखता है, जिससे runtime पर सही function मिलता है.

Base class का destructor virtual क्यों होना चाहिए?

ताकि base pointer से derived object delete करने पर derived destructor भी चले; वरना सिर्फ base हिस्सा destroy होता है और derived हिस्से के resources leak होते हैं.