c++constructorlate-bindingearly-binding

Initialize a object with a derived class constructor


Consider the following C++ code:

#include <iostream>

using std::cout;

class A
{
public:
    int a;

    A():a(0)
    {
        cout << "A constructor\n";
    }

    virtual void f()
    {
        cout << "f inside A\n";
    }
};

class C : public A
{
public:
    int c;

    virtual void f()
    {
        cout << "f inside C\n";
    }

    C():c(0)
    {
        cout << "C constructor\n";
    }
};

int main()
{
    A varA = C();

    cout << "Size of C class: " << sizeof(C) << "\n";
    cout << "Size of varA object: " << sizeof(varA) << "\n";

    C* varC = static_cast<C*>(&varA);
    varC->f();

    cout << "varC->a is " << varC->a << "\n";
    cout << "varC->c is " << varC->c << "\n";
}

The output of this program is:

A constructor
C constructor
Size of C class: 16
Size of varA object: 8
f inside A
varC->a is 0
varC->c is 1726166356

I initialize the varA object with the constructor of class C. Constructors of A and C class are called, but the varA is a simply a A object. I cast the address of varA to C* type and I try to call its f() function, but it prints the f() function of class A, so I deduce that it is use the early binding mechanism to call it. I think if I call the constructor of derived class, like this case, I obtain the same object if I had called the base constructor. I think the only difference is the other constructors are called. Is my supposition right or there are any other differences?


Solution

  • Classic example of slicing. A varA = C(); leaves you with object of static and dynamic type of A. As a result, C* varC = static_cast<C*>(&varA); exhibits undefined behavior.