0

I'm working on a C++ code example that uses virtual inheritance and multiple inheritance. In my code, I've noticed that I have to call the constructor of the Base class in each derived class, even though the values passed to the base class constructor are not used. Why is this necessary, and can I avoid calling the base class constructor in every derived class and only call it in the Combined class?

#include <stdio.h>

class Base
{
    public:
        Base(int n) : n(n) {}
        int n;
};

class AddsSomething1 : virtual public Base
{
    public:
        AddsSomething1() : Base(1)
        {
            printf("AddsSomething1(): base %d\n", this->n);
        }

        int something1;
};

class AddsSomething2 : virtual public Base
{
    public:
        AddsSomething2(): Base(2)
        {
            printf("AddsSomething2(): base %d\n", this->n);
        }

        int something2;
};

class AddsSomething3 : virtual public Base
{
    public:
        AddsSomething3() : Base(3)
        {
            printf("AddsSomething3(): base %d\n", this->n);
        }

        int something3;
};

class Combined : public AddsSomething1, public AddsSomething2, public AddsSomething3
{
    public:
        Combined(int n) : Base(123)
        {
            printf("Combined(): base %d\n", this->n);
        }
};

int main()
{
    Combined(123);
}

Output:

AddsSomething1(): base 123
AddsSomething2(): base 123
AddsSomething3(): base 123
Combined(): base 123

2 Answers 2

1

A virtual base's constructor must be invoked from every derived type because it is always and only the single most-derived type constructor that actually invokes the virtual bases constructor. Every other base in the inheritance chain learns that the virtual base has already been constructed and skips that step.

Sign up to request clarification or add additional context in comments.

6 Comments

I understand what you are trying to say but I have a hard time understanding what you mean by Every other base...
Say you have struct V1 { ... }; struct B1 : virtual V1 { ... }; struct B2 : virtual V1 { ... }; struct D : B1, B2 { ... }; Without virtual there would be two V1 instances in the tree and the construction order would be V1, B1, V1, B2, D. With virtual it is V1, B1, B2, D. A type only knows that it is the most-derived by the fact that the virtual base has not yet been initialized.
Are there any exceptions to this rule? I am also playing with templates and I think I found an example where I don't have to call Base() from deriving class. Can I contact you?
@PoProstuMieciek : If the virtual base has a default constructor then it does not need to be explicitly invoked. Such a constructor will, however, be invoked as normal, just by the most-derived type rather than the left-most direct base.
What about if the ctor is invoked with different parameters?
|
0

No, you can't avoid invoking parent class constructor because they are invoked in implicity. Also, you don't need to invoke them in explicity. You know, we can't imagine the successful inheritance without invoking them.

Thank you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.