C 语言设计:孩子称呼所有虚拟祖先构造函数
C++ language design: child calls all virtual ancestor constructors
这个问题的内容取决于我对虚拟继承在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的角度来看),只需要直接从其中一个继承时,就需要手动处理所有祖先。
我想我一天结束时要问的是:
- 当只有一个父母时,语言无法将祖先初始化委托给父母?
- 该语言为什么不允许祖先构造师的委派?例如
Child::Child(void): Parent1(), Parent2() {}
导致Parent1
初始化Grandparent
,而Child::Child(void): Parent2(), Parent1() {}
导致Parent2
初始化Grandparent
,而Child::Child(void): Grandparent("The child overrides."), Parent1(), Parent2()
明确初始化Grandparent
。 - 标准委员会是否有任何计划在未来版本中更改C 虚拟继承?
也许语言设计师可以做得更好(老实说,我发现了几个情况下,在C 开发的15年中,虚拟继承是有意义的),但是我们只要求规则最派生的类构建了几乎继承的基础。确实有意义的是,只有当构造最衍生的类型时,我们实际上知道虚拟基础要在哪里"实时"。
除最多衍生的类型将构建虚拟基础以外的任何类型的规则都会使本来已经复杂的业务变得更加多。
相关文章:
- 虚拟决赛作为安全
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- 如何在C++中获得"静态纯虚拟"功能?
- C++无法定义虚拟函数 OUTER 类和头文件
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 大小虚拟继承中的派生类
- 链接器找不到在虚拟类 c++ 中访问的静态字段的符号
- 使用 C++ 和 i2c 工具从虚拟 i2c 写入和读取
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 如果整个应用程序是虚拟映射的,为什么 new 会进行系统调用?
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- std::is_trivially_copyable_v 关于虚拟功能
- 删除C++继承中虚拟类成员的代码重复
- C 语言设计:孩子称呼所有虚拟祖先构造函数
- 为什么在派生最多的类的初始值设定项列表中显式调用虚拟基类构造函数的规则,而较老的祖先已经拥有它?
- 应该在所有继承级别还是仅在祖先级别声明虚拟函数
- 是否可以显式使用祖先的虚拟类方法作为派生方法?