3

上下文 1:D 类:公共 B1,公共 B2{};

上下文 2:B2 带 B1 初始化: B2( B1 * ) //B2 的构造函数

我的问题在 D 的初始化列表中:

D::D() : B1(), B2( ? )... 应该是什么?

我不想在 ? 地方,因为在初始化列表中使用“this”是不好的。并且由于 B1 部分已经初始化,使用它是有意义的。

我应该怎么办 ?

4

2 回答 2

3

使用 的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.
于 2010-04-12T05:21:44.067 回答
1

这是有风险的代码。如前所述,B1 是在 B2 之前构造的,因此您可以安全地执行此操作,但如果类定义发生更改,情况将不再如此,并且它位于代码中不相关的位置,因此您看不到当你破坏它时你正在破坏的代码。

我会仔细研究这个设计 - 是否可以更改它以使其变得不必要?您可以将事物移动到成员中以封装而不是继承 - D 真的是 B1 和 B2 吗?

于 2010-04-12T05:51:17.357 回答