All Courses
OOP: POLYMORPHISM

Virtual Destructor

A virtual destructor is a destructor declared with the virtual keyword in a base class.

It is important when deleting derived objects through base-class pointers.

The Problem

In polymorphism, this is common:

Base* ptr = new Derived();
delete ptr;

If the base destructor is not virtual, deleting through Base* may fail to call the derived destructor correctly.

That can cause resource leaks.

Correct Example

#include <iostream>
using namespace std;

class Base {
public:
    virtual ~Base() {
        cout << "Base destructor" << endl;
    }
};

class Derived : public Base {
private:
    int* data;

public:
    Derived() : data(new int[5]) {
        cout << "Derived constructor" << endl;
    }

    ~Derived() override {
        delete[] data;
        cout << "Derived destructor" << endl;
    }
};

int main() {
    Base* ptr = new Derived();
    delete ptr;

    return 0;
}

Output:

Derived constructor
Derived destructor
Base destructor

Why This Order Matters

The actual object is Derived.

So destruction must happen like this:

Derived part first
Base part second

A virtual destructor makes sure that happens when deleting through a base pointer.

Rule To Remember

If a base class has any virtual function, it should usually have a virtual destructor.

Good pattern:

class Shape {
public:
    virtual ~Shape() = default;
    virtual void draw() const = 0;
};

Can a Destructor Be Called by the Programmer?

Yes, a programmer can explicitly call a destructor:

// obj.~ClassName();

But in normal C++ code, you almost never do this manually for ordinary objects. Destructors are called automatically when objects go out of scope or when delete is used for heap objects.

Viva Answer

A virtual destructor ensures that when a derived object is deleted through a base-class pointer, the derived destructor runs first and then the base destructor runs. Polymorphic base classes should have virtual destructors.

Quick Check

  1. Why should a polymorphic base class have a virtual destructor?
  2. In destruction, which runs first: derived destructor or base destructor?
  3. Is manually calling a destructor common in normal code?