Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding virtual base classes and constructor calls

I'm a bit confused about how virtual base classes work. In particular, I was wondering how the constructor of the base class gets called. I wrote an example to understand it:

#include <cstdio>
#include <string>
using std::string;

struct A{
    string s;
    A() {}
    A(string t): s(t) {}
};

struct B: virtual public A{
    B(): A("B"){}
};

struct C: virtual public A {};

struct D: public B, public C {};

struct E: public C, public B {};

struct F: public B {};

int main(){
    D d;
    printf("\"%s\"\n",d.s.c_str());
    E e;
    printf("\"%s\"\n",e.s.c_str());
    F f;
    printf("\"%s\"\n",f.s.c_str());
    B b;
    printf("\"%s\"\n",b.s.c_str());
}

Which outputs

""
""
""
"B"

I wasn't sure what would happen in the first two cases, but for the third one at least I was expecting the output to be "B". So now I'm just confused. What are the rules for understanding how the constructor of A gets called?

like image 229
pythonic metaphor Avatar asked Jun 23 '11 23:06

pythonic metaphor


People also ask

Why is virtual base class constructor called first?

Any non-virtual bases are then constructed before the derived class constructor is called. If a derived class has one virtual base class and other non-virtual base class, then the constructor of the virtual base class will be constructed first even though it appears at second position in the declaration.

What are virtual base classes?

Overview. Virtual base classes in C++ are used as a way of preventing multiple instances of a given class from appearing in an inheritance hierarchy when using multiple inheritances.

Does a virtual class need a constructor?

The virtual mechanism works only when we have a base class pointer to a derived class object. In C++, the constructor cannot be virtual, because when a constructor of a class is executed there is no virtual table in the memory, means no virtual pointer defined yet. So, the constructor should always be non-virtual.

How do you call base class in constructor?

You can call the base class constructor from the child class by using the super() which will execute the constructor of the base class. Example: Javascript.


1 Answers

There is always just one constructor call, and always of the actual, concrete class that you instantiate. It is your responsibility to endow each derived class with a constructor which calls the base classes' constructors if and as necessary, as you did in B's constructor.

Update: Sorry for missing your main point! Thanks to ildjarn.

However, your B inherits virtually from A. According to the standard (10.1.4 in the FIDS), "for each distinct baseclass that is specified virtual, the most derived object shall contain a single base class subobject of that type". In your case this means that when constructing the base, your class F immediately calls A's default constructor, not B's.

like image 171
Kerrek SB Avatar answered Nov 15 '22 21:11

Kerrek SB