Sven van den Boogaart
Sven van den Boogaart

Reputation: 12327

C++ virtual function in constructor

Im reading this article on constructors for c++

We recommend that you be careful when you call virtual functions in constructors. Because the base class constructor is always invoked before the derived class constructor, the function that's called in the base constructor is the base class version, not the derived class version. In the following example, constructing a DerivedClass causes the BaseClass implementation of print_it() to execute before the DerivedClass constructor causes the DerivedClass implementation of print_it() to execute:

the example:

    class BaseClass {
    public:
        BaseClass() {
            print_it();
        }
        virtual void print_it() {
            cout << "BaseClass print_it" << endl;
        }
    };

    class DerivedClass : public BaseClass {
    public:
        DerivedClass() {
            print_it();
        }
        virtual void print_it() {
            cout << "Derived Class print_it" << endl;
        }
    };

    int main() {

        DerivedClass dc;
    }

Here's the output:

BaseClass print_it
Derived Class print_it

I tried this code and the output is as stated above. However I also tried the same example without the virtual keyword:

    class BaseClass {
    public:
        BaseClass() {
            print_it();
        }
        void print_it() {
            cout << "BaseClass print_it" << endl;
        }
    };

    class DerivedClass : public BaseClass {
    public:
        DerivedClass() {
            print_it();
        }
        void print_it() {
            cout << "Derived Class print_it" << endl;
        }
    };

    int main() {

        DerivedClass dc;
    }

and got the same result.

So what is the difference and what is the danger they are warning for?

@marked as duplicate:

This question is different as the consturctors both call the virtual method instead of one constructor calling the virtual method.

Upvotes: 2

Views: 608

Answers (1)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385164

There is no difference. That's the danger.

If you did not know better then you might expect this instead:

Derived Class print_it
Derived Class print_it

The expectation is there because if you call the virtual print_it() from functions in Base, polymorphism means you'll usually get the Derived version instead.

But, when you write it in the Base constructor, the Base part of the object is still under construction, and the "dynamic type" of the object under construction is still Base, not Derived. So you do not get the usual polymorphic behaviour.

The article is warning you about this fact.

Upvotes: 7

Related Questions