上下文 1:D 类:公共 B1,公共 B2{};
上下文 2:B2 带 B1 初始化: B2( B1 * ) //B2 的构造函数
我的问题在 D 的初始化列表中:
D::D() : B1(), B2( ? )... 应该是什么?
我不想在 ? 地方,因为在初始化列表中使用“this”是不好的。并且由于 B1 部分已经初始化,使用它是有意义的。
我应该怎么办 ?
上下文 1:D 类:公共 B1,公共 B2{};
上下文 2:B2 带 B1 初始化: B2( B1 * ) //B2 的构造函数
我的问题在 D 的初始化列表中:
D::D() : B1(), B2( ? )... 应该是什么?
我不想在 ? 地方,因为在初始化列表中使用“this”是不好的。并且由于 B1 部分已经初始化,使用它是有意义的。
我应该怎么办 ?
使用 的B1
部分是可以的,this
因为它已经初始化了。§12.6.2/5:“直接基类应按声明顺序初始化,因为它们出现在基本说明符列表中(无论内存初始化器的顺序如何)。”
这里的 base-specifier-list 是class D : public B1, public B2
,而 mem-initializer-list 是D::D() : B1(), B2( … )
。
不过,我会说这有“代码气味”。
编辑:现在我了解您的担忧,是否this
在构造函数的主体之外未定义,不包括成员初始化程序。允许这样做的语言隐藏在两个示例之间,起初我错过了它。第 7 段:“mem-initializer 的表达式列表中的名称在指定 mem-initializer 的构造函数的范围内进行评估。”
如果B2
确实需要保留指向 a 的指针B1
,并且该指针将始终指向派生最多的对象内部,请考虑虚拟继承。
class B1 {};
class B2 : virtual B1 {}; // under the hood, B2 has a pointer to B1.
class D : public virtual B1, public B2 {}; // D has a pointer too
// Only the most-derived class (the one actually used for instantiation)
// implements space for and initialization of the B1.
这是有风险的代码。如前所述,B1 是在 B2 之前构造的,因此您可以安全地执行此操作,但如果类定义发生更改,情况将不再如此,并且它位于代码中不相关的位置,因此您看不到当你破坏它时你正在破坏的代码。
我会仔细研究这个设计 - 是否可以更改它以使其变得不必要?您可以将事物移动到成员中以封装而不是继承 - D 真的是 B1 和 B2 吗?