C 语言设计:孩子称呼所有虚拟祖先构造函数

C++ language design: child calls all virtual ancestor constructors

本文关键字:虚拟 祖先 构造函数 语言 孩子      更新时间:2023-10-16

这个问题的内容取决于我对虚拟继承在c 中的工作方式的理解。纠正我,如果这是错误的。

在C 中,虚拟继承需要(隐式或显式)调用子类中所有祖先类的构造函数,这也阻止了任何祖先调用另一个祖先的构造师。换句话说:

class Grandparent{
public:
    Grandparent(string const& message) { 
        std::cerr << "Grandparent says " << message << 'n';
    }
};
class Parent : virtual Grandparent{
public:
    Parent(string const& message)
        : Grandparent(string("hello parent. Parent says ") + message)
    {}
}
class Child : virtual Parent{
public:
    Child(void)
        : Grandparent(""), // Required, since Grandparent has no default ctor
          Parent("hello child. Child says are we there yet"?)
    {}
}

在此示例中,构造Child实例应简单地将"祖父母Said n"打印为标准错误,因为Parent构造函数对Grandparent构造函数的调用被删除。换句话说,由孩子执行的"有效" Parent构造函数看起来像这样:

Parent(string const& message) {}

但这似乎是违反直觉和问题的。当父母已经这样做时,为什么孩子班必须明确调用祖父母的构造函数?我知道钻石问题,在这里不适用,因为孩子课只有一个直接父母。该语言保证父母已经称其为祖父母的构造函数,那么为什么要将此任务委派给孩子?

此外,父母对祖父母建筑商的呼吁的删除阻碍了继承的有效性。如果孩子想真正继承父母的行为,则必须复制某些父母的初始化代码。例如:

Parent::Parent(string const& msg)
    : Grandparent(some_parent_logic(msg))
    {}
Child::Child(string const& msg)
    : Parent("doesn't matter anymore"),
      GrandParent(some_child_logic(some_parent_logic(msg))) // Can't inherit implicit use of parent logic

,如果您在呼叫祖先构造函数时不使用复杂的逻辑,那么这并不是一个大问题,但是随着继承链的增长,冗余问题往往会增长。似乎有点亵渎(从OO的角度来看),只需要直接从其中一个继承时,就需要手动处理所有祖先。

我想我一天结束时要问的是:

  1. 当只有一个父母时,语言无法将祖先初始化委托给父母?
  2. 该语言为什么不允许祖先构造师的委派?例如Child::Child(void): Parent1(), Parent2() {}导致Parent1初始化Grandparent,而Child::Child(void): Parent2(), Parent1() {}导致Parent2初始化Grandparent,而Child::Child(void): Grandparent("The child overrides."), Parent1(), Parent2()明确初始化Grandparent
  3. 标准委员会是否有任何计划在未来版本中更改C 虚拟继承?

也许语言设计师可以做得更好(老实说,我发现了几个情况下,在C 开发的15年中,虚拟继承是有意义的),但是我们只要求规则最派生的类构建了几乎继承的基础。确实有意义的是,只有当构造最衍生的类型时,我们实际上知道虚拟基础要在哪里"实时"。

除最多衍生的类型将构建虚拟基础以外的任何类型的规则都会使本来已经复杂的业务变得更加多。