Virtual Functions
Written and reviewed by Gagan Bhardwaj · Senior IT Faculty · 15+ years’ experience
What is a virtual function?
A virtual function is a member function marked virtual in a base class, designed to be overridden by derived classes. Its point is dynamic dispatch: when you call it through a base-class pointer or reference, C++ runs the version belonging to the actual object, not the pointer's type.
The problem it solves
Without virtual, a call through a base pointer always runs the base version, ignoring the override. Compare:
class Base { public: virtual void hi() { cout << "Base\n"; } };
class Derived : public Base { public: void hi() override { cout << "Derived\n"; } };
int main() {
Base *p = new Derived();
p->hi(); // "Derived" — thanks to virtual
delete p;
}Derived
Remove virtual and this would print Base instead.
The override keyword
Add override to a derived function you intend as an override. If it does not actually match a base virtual, the compiler stops you — catching typos in the signature:
class Shape { public: virtual double area() { return 0; } };
class Circle : public Shape {
double r;
public:
Circle(double x) : r(x) {}
double area() override { return 3.14159 * r * r; } // safe
};How it works: the vtable
Most compilers implement this with a vtable — a per-class table of function pointers. Each polymorphic object holds a hidden pointer to its class's vtable, and a virtual call looks up the right function there at run time. This is why virtual calls have a tiny overhead over ordinary calls.
Virtual destructors
If you delete a derived object through a base pointer, the destructor must be virtual — otherwise only the base part is destroyed and the derived resources leak:
class Base {
public:
virtual ~Base() { cout << "~Base\n"; } // virtual destructor
};
class Derived : public Base {
public:
~Derived() { cout << "~Derived\n"; }
};
// delete (Base*)new Derived(); → ~Derived then ~BaseAny class with a virtual function should also have a virtual destructor.
Overriding vs hiding
True overriding needs a matching signature on a virtual base function. If the base function is not virtual, or the signatures differ, the derived function merely hides the base one — no dynamic dispatch. The override keyword guards against this by mistake.
Common mistakes
- Forgetting
virtual, so overrides are ignored through base pointers. - Omitting a virtual destructor in a polymorphic base (resource leak).
- A slightly different signature causing hiding instead of overriding (use
override). - Expecting dynamic dispatch when calling on an object rather than a pointer/reference.
For a compact syntax reference and quick example, see the virtual functions syntax page. For the wider idea, see polymorphism.
Build a Shape base with a virtual area() and a virtual destructor. Derive Circle and Rectangle. Store them via Shape* pointers and print each area through the base pointer.
Summary
- A virtual function enables run-time dispatch to the right override.
- Call it through a base pointer/reference for polymorphism.
overridemakes the compiler verify your override.- Compilers use a vtable to resolve virtual calls at run time.
- Always give a polymorphic base class a virtual destructor.
Frequently Asked Questions
What is a virtual function in C++?
virtual keyword in a base class, meant to be overridden in derived classes. When called through a base-class pointer or reference, the version matching the actual object is chosen at run time, enabling run-time polymorphism.What does the override keyword do in C++?
override keyword tells the compiler that a function is meant to override a virtual function from the base class. If the signature does not actually match a base virtual function, the compiler reports an error, which catches subtle mistakes early.How do virtual functions work internally in C++?
Why do you need a virtual destructor in C++?
What is the difference between overriding and function hiding in C++?
Virtual function क्या है?
Virtual function एक member function है जो base class में virtual चिह्नित होता है, derived classes द्वारा override होने को बना। इसका उद्देश्य dynamic dispatch है: जब आप इसे base-class pointer या reference के ज़रिए call करते हैं, C++ वास्तविक object का version चलाता है, pointer के type का नहीं।
यह किस समस्या को हल करता है
virtual के बिना, base pointer के ज़रिए call हमेशा base version चलाता है, override को अनदेखा करते हुए। तुलना करें:
class Base { public: virtual void hi() { cout << "Base\n"; } };
class Derived : public Base { public: void hi() override { cout << "Derived\n"; } };
int main() {
Base *p = new Derived();
p->hi(); // "Derived" — virtual ki wajah se
delete p;
}Derived
virtual हटाएँ और यह इसके बजाय Base print करेगा।
override keyword
जिस derived function को आप override बनाना चाहते हैं उसमें override जोड़ें। अगर यह वास्तव में किसी base virtual से मेल न खाए, compiler आपको रोकता है — signature में typos पकड़ते हुए:
class Shape { public: virtual double area() { return 0; } };
class Circle : public Shape {
double r;
public:
Circle(double x) : r(x) {}
double area() override { return 3.14159 * r * r; } // safe
};यह कैसे काम करता है: vtable
अधिकांश compilers इसे vtable से लागू करते हैं — प्रति-class function pointers की तालिका। हर polymorphic object अपनी class के vtable का एक छिपा pointer रखता है, और virtual call run time पर वहाँ सही function ढूँढता है। इसीलिए virtual calls में सामान्य calls पर एक छोटा overhead होता है।
Virtual destructors
अगर आप base pointer के ज़रिए derived object delete करते हैं, destructor virtual होना चाहिए — अन्यथा केवल base हिस्सा नष्ट होता है और derived resources leak होते हैं:
class Base {
public:
virtual ~Base() { cout << "~Base\n"; } // virtual destructor
};
class Derived : public Base {
public:
~Derived() { cout << "~Derived\n"; }
};
// delete (Base*)new Derived(); → pehle ~Derived phir ~Baseकिसी भी class में virtual function हो तो उसमें virtual destructor भी होना चाहिए।
Overriding बनाम hiding
सच्चे overriding को virtual base function पर मेल खाता signature चाहिए। अगर base function virtual न हो, या signatures भिन्न हों, derived function केवल base को छिपाता है — कोई dynamic dispatch नहीं। override keyword इसे गलती से होने से रोकता है।
आम गलतियाँ
virtualभूलना, तो base pointers के ज़रिए overrides अनदेखे होते हैं।- Polymorphic base में virtual destructor छोड़ना (resource leak)।
- थोड़ा अलग signature overriding के बजाय hiding पैदा करना (
overrideइस्तेमाल करें)। - Pointer/reference के बजाय object पर call करते समय dynamic dispatch की उम्मीद।
संक्षिप्त syntax reference और त्वरित उदाहरण के लिए, virtual functions syntax page देखें। व्यापक विचार के लिए, polymorphism देखें।
एक Shape base बनाएँ जिसमें virtual area() और virtual destructor हो। Circle और Rectangle derive करें। इन्हें Shape* pointers से रखें और हर area base pointer के ज़रिए print करें।
सारांश
- Virtual function सही override को run-time dispatch सक्षम करता है।
- Polymorphism के लिए इसे base pointer/reference के ज़रिए call करें।
overridecompiler से आपका override सत्यापित कराता है।- Compilers virtual calls run time पर हल करने को vtable इस्तेमाल करते हैं।
- Polymorphic base class को हमेशा virtual destructor दें।