Virtual function call in destructor

A C++ destructor contains a call to a virtual function.

As a general rule, you should never call virtual functions in constructors or destructors. If you do, those calls will never go to a more derived class than the currently executing constructor or destructor. In other words, during construction and destruction, virtual functions aren't virtual.

Suppose you have a class A whose destructor contains a call to a virtual function f. Suppose class B is derived from A, and B defines its own member function f. During destruction of an instance of B, A's destructor will be called after B's destructor. When A's destructor calls f, it will call A's definition of f, not B's definition of f. The reason it must do this is because the derived class has already been destroyed. B's definition of f cannot be called after B's destructor has been called.

ID

Observation

Description

1

Call site

This shows where the virtual function was called

Example


#include <stdio.h>

class A
{
public:
    A() {
    }

    void intermediate_call() {
        virtual_function();
    }

    virtual void virtual_function() {
        printf("A::virtual_function called\n");
    }

    virtual ~A() {
        // Bad: virtual function call during object destruction
        intermediate_call();
    }
};

class B : public A
{
public:
    // override virtual function in A
    void virtual_function() {
        printf("B::virtual_function called\n");
    }
};

int main(int argc, char **argv)
{
    B myObject;

    // This call behaves like a normal virtual function call.
    // Print statement shows it invokes B::virtual_function.
    myObject.virtual_function();

    // Call to virtual_function during destruction doesn't
    // behave like normal virtual function call.
    // Print statement shows it invokes A::virtual_function,
    // even though we are destroying an instance of B, not A.
}
        

Copyright © 2010, Intel Corporation. All rights reserved.