1

我努力在标题中简洁地描述这个问题,所以如果你理解这个问题并且有一个更好的标题,请推荐。

我已经制作了我的问题的精简版本,它尽可能小,因此所有函数都是内联定义的,所以请原谅,实际代码不是这样的。

这是我的结构:

class iobject
{
public:
    virtual bool isValid (void) = 0;
};

class object : virtual public iobject
{
public:
    object (void) { }
    virtual ~object () {}
    virtual bool isValid (void) { return true; }
};

所以上面,一个简单地跟踪对象是否有效的接口+实现......想象引擎/系统中的所有对象都将派生自这个单一对象。

class ibase : public virtual iobject
{
public:
    virtual void show (void) = 0;
};

class base : public virtual object,
             public virtual ibase
{
public:
    base (int value) : object() { m_value = value; }
    virtual ~base () {}
    virtual void show (void) { std::cout << m_value << std::endl; }

private:
    int m_value;
};

现在我有一个假设的类,它只是存储一个数字并打印它。它来源于对象。所以“钻石”是完整的。

class derived1 : public virtual base
{
public: 
    derived1 (int value) : base (value) {}
    virtual ~derived1 () {}
};

现在我从基类派生。关于这个派生类要注意的是,我具有与基类相同的构造函数参数(int 值)。

class derived2 : public virtual derived1
{
public:
    derived2 (void) : derived1 (15) {}
    virtual ~derived2 () {}
};

最后我从这个派生类派生。但是,请注意,此类没有任何构造函数参数。相反,这个类在内部应该知道这个例子中的值应该是 15。

我的期望是,当我实例化 derived2 时,它会用值 15 构造 derived1 并将其传递给对象。我希望做到以下几点:

derived1 works(1234);
derived2 doesNotWork;

works.show();
doesNotWork.show();

但是当我尝试这个时,我得到:

error C2512: 'base::base' : no appropriate default constructor available

如果我添加一个空的 base::base 构造函数,那么我最终会得到未定义的 m_value (但无论如何都尝试过)

我似乎遗漏了一些明显的东西......有人可以突出显示吗?

4

2 回答 2

1

将derived2更改为:

derived2(void) : derived1(15), base(15) {}

同样的问题出现在这里: 为什么在虚拟继承中调用默认构造函数?

此常见问题解答中描述了答案:http: //www.parashift.com/c++-faq-lite/virtual-inheritance-ctors.html

简而言之:C++ 不会分层调用虚拟构造函数。最派生类负责调用所有虚拟基类的构造函数。因此,您必须显式调用 derived1() 和 base(),因为它们带有参数。链接的常见问题解答暗示这里的最佳实践是使虚拟基类仅具有无参数构造函数。

于 2014-07-03T18:24:15.053 回答
0

您没有菱形继承,这里没有共享基类( derived2 -> derived1 -> base -> ( object -> iobject ), ibase ),这个链中没有任何重复项。因此,您不需要虚拟继承,因此只需public virtual全面放弃即可。我意识到这是一个人为的示例,与您的实际用法不符,但根据我的经验,您实际上需要使用虚拟调用进行多重继承是非常罕见的,如果可能的话,您通常应该远离这种情况(对象大小,调用开销和指针行为的一般讨厌)。

于 2014-07-03T02:05:39.563 回答