【问题标题】:Do I need to initialize base class in virtual inheritance classes' constructors for diamond inheritanceproblem?对于菱形继承问题,我是否需要在虚拟继承类的构造函数中初始化基类?
【发布时间】:2019-11-28 14:22:18
【问题描述】:

我用虚拟继承解决了菱形问题。这里的情况不是钻石但我想了解虚拟继承:

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)
    {}
};

因此,由 Target 一起继承的 Virtual 或 Virtual2 将具有单个 Base 实例。在这里,我认为在 Target 构造函数中调用 Base 构造函数将创建所需的实例,我可以在 Virtual 中省略 Base 构造函数,但随后出现错误:

错误:“Virtual”的构造函数必须显式初始化没有默认构造函数的基类“Base”

那么,如果假设不被调用,那里的构造函数真的有必要吗?

在实际情况中,我在构造函数中使用 lambda 对参数进行了一些更改,所以我不知道是否需要重复。

【问题讨论】:

  • fwiw 我试图改正错别字,但在把它们全部赶上之前我已经累了
  • 是的,Target也需要初始化Base
  • "但我不知道为什么 Virtual 需要" - BaseVirtual 都不是默认可构造的,因此您需要指定构造函数并提供参数它需要。但是请注意,在实例化 Target 时,Base 只会直接从 Target 初始化,并且您传递给 Virtual 的参数只会被 Virtual:s 构造函数使用,而不是 Base: @ 987654323@

标签: c++ c++17


【解决方案1】:

正如您所写,VirtualTarget 都需要 为Base 提供构造函数。

如果你把Virtual抽象化,那么它就不需要 不再初始化Base

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 {}
};

【讨论】:

    【解决方案2】:

    这是必要的,因为否则编译器不知道如何调用Virtual 的构造函数,当对象不是进一步继承链的一部分时。您不必为Virtual 提供构造函数,但是当您这样做时,您还需要初始化Base。 (如果你不为Virtual 提供构造函数,你就不能创建这个类的(子)对象,这使得它在大多数情况下都无用)。

    如果Virtual 是一个抽象类,那么它的构造函数永远不能被自己调用(只能从进一步的派生类中调用),编译器会让你跳过Base 的初始化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-24
      • 2020-06-05
      • 2015-06-21
      • 2014-11-23
      • 1970-01-01
      • 2012-12-19
      • 2021-02-02
      • 1970-01-01
      相关资源
      最近更新 更多