Introduction

Virtual Input/Output

Static Invocation of a Virtual Function

Virtual Functions and Default Arguments

Virtually a Virtual new Operator

Virtual Functions, Constructors, and Destructors

Virtual functions do not behave polymorphically during base class construction or destruction. Because during construction, the derived part of the object does not yet exist. And during destruction, the derived part of the object has already been destroyed. So:

This prevents accessing uninitialized or destroyed data in derived classes, which could lead to crashes or undefined behavior.

#include <iostream>

class Base {
public:
    Base() {
        std::cout << "Base constructor\n";
        call();  // virtual function call inside constructor
    }

    virtual ~Base() {
        std::cout << "Base destructor\n";
        call();  // virtual function call inside destructor
    }

    virtual void call() const {
        std::cout << "Base::call()\n";
    }
};

class Derived : public Base {
public:
    Derived() {
        std::cout << "Derived constructor\n\n";
    }

    ~Derived() {
        std::cout << "Derived destructor\n";
    }

    void call() const override {
        std::cout << "Derived::call()\n";
    }
};

int main() {

    Derived d;

    return 0;
}

Output:

Base constructor
Base::call()
Derived constructor

Derived destructor
Base destructor
Base::call()