子构造函数使用祖父构造函数

  • 本文关键字:构造函数 c++ inheritance
  • 更新时间 :
  • 英文 :


我有以下具有虚拟GrandParent和非虚拟ParentChild的类层次结构:

class GrandParent {
protected:
explicit GrandParent(const float &max_dur);
virtual ~GrandParent() {}
private:
const float _max_dur;
};
class Parent : public virtual GrandParent {
public:
explicit Parent(const float &max_dur = 0);
};
class Child : public Parent {
public:
explicit Child(const float &max_dur = 0);
};

它们的构造函数嵌套如下:

// GrandParent constructor
GrandParent::GrandParent(const float &max_dur)
: _max_dur{max_dur} {}
// Use GrandParent constructor
Parent::Parent(const float &max_dur)
: GrandParent{max_dur} {}
// Use Parent constructor
Child::Child(const float &max_dur)
: Parent{max_dur} {}                        // <- error occurs here
当我构建时,我得到以下错误消息:
error: no matching function for call to ‘GrandParent::GrandParent()’

Codesnippet这里。

似乎忽略了Child构造函数,而是跳转到GrandParent。修改Child构造函数以直接调用GrandParent构造函数(从而跳过一代),我可以绕过错误,但这似乎是错误的方法。

提前感谢您的帮助!

<标题>

解决方案修复了463035818-is-not-a-number对显式调用GrandParent的构造函数的回答和对同时调用Parent的构造函数的建议:

Child::Child(const float &max_dur)
: GrandParent{max_dur}, Parent{max_dur} {}

来自faq:

当我从使用虚拟继承的类继承时,我需要知道哪些特殊的注意事项?

派生类的初始化列表直接调用虚基类的ctor。

因为虚基类的子对象在实例中只出现一次,所以有特殊的规则来确保虚基类的构造函数和析构函数在每个实例中只被调用一次。c++规则规定在所有非虚基类之前构造虚基类。作为一名程序员,你需要知道的是:在你的类继承层次结构中的任何地方,虚拟基类的构造函数都是由"最派生"类的构造函数调用的。

Child的构造函数直接调用GrandParent的构造函数,因为GrandParent是虚基。因为没有显式地调用它,所以调用了默认构造函数,但是GrandParent没有默认构造函数。

修改子构造函数以直接调用祖父母构造函数(从而跳过一代),我可以绕过错误,但这似乎是错误的方法。

这正是正确的方法。Child的构造函数确实调用GrandParent的构造函数,当GrandParent是虚基类而Child是派生最多的类时,您无法对此做任何事情。你可以做的是:选择正确的构造函数,而不是让编译器尝试调用不存在的默认构造函数。

最新更新