简体   繁体   中英

Do I need to initialize base class in virtual inheritance classes' constructors for diamond inheritanceproblem?

I have the diamond problem resolved with virtual inheritance. The situation here is not a diamond but I want to understand the virtual inheritance:

class Base
{
public:
    explicit Base(int arg)
        : arg { arg }
    {}
    const int arg;
};

class Virtual : public virtual Base
{
public:
    explicit Virtual(int _arg)
        //: Base(_arg)
    {}
};

class Target : public virtual Virtual
{
public:
    explicit Target(int _arg)
        : Base(_arg),
          Virtual(_arg)
    {}
};

So, the idea is that Virtual or Virtual2, inherited together by Target, will have single Base instance. Here I thought that calling Base constructor in Target constructor will create the instance needed and I could omit Base constructor in Virtual, but then I'm getting an error:

error: constructor for 'Virtual' must explicitly initialize the base class 'Base' which does not have a default constructor

So, is the constructor there really necessary if it's suppose not to be called?

In real situation I am making some changes to arguments with lambda within the constructors so I don't know if it needs to be repeated.

As you have written, both Virtual and Target needs to provide a constructor for Base .

If you make Virtual abstract, then it does not need to initialize Base any longer.

class Base
{
public:
    explicit Base(int arg)
        :  arg(arg)
    {}
private:
    const int arg;
};

class Virtual : public virtual Base
{
public:
    explicit Virtual(int arg)
    {}
private:
    virtual void foo() = 0;
};

class Target : public virtual Virtual
{
public:
    explicit Target(int arg)
        : Base(arg), Virtual(arg)
    {}
private:
    virtual void foo() override {}
};

It is necessary because otherwise the compiler doesn't know how to call the costructor of Virtual on its own, when the object is not a part of furher inheritance chain. You don't have to provide a constructor for Virtual , but when you do, you need to initialise Base as well. (If you don't provide a constructor for Virtual , you cannot make (sub)objects of this class, which makes it useless for most purposes).

If Virtual is an abstract class then its constructor can never be called on its own (only from further derived classes) and the compiler will let you skip initialisation of Base .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM