【问题标题】:Use super class's address/pointer in initialization list在初始化列表中使用超类的地址/指针
【发布时间】:2011-02-06 21:05:36
【问题描述】:

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

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

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

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

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

我该怎么办?

【问题讨论】:

    标签: c++ multiple-inheritance superclass this-pointer


    【解决方案1】:

    可以使用thisB1 部分,因为它已经初始化。 §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 确实需要保留指向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不是继承关系,我不想为了解决这个问题而改变B2。
    【解决方案2】:

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

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

    【讨论】:

    • 一个成员依赖另一个成员是很常见的,如果定义发生变化,开发人员负责更改实现。我可以改变我的设计,这很容易,但我想发现这个问题的技术方面,因为它很有意义。
    • @JQ:你说的是“成员”而不是“基地”。如果他们实际上是成员,那么您就没有这个问题。是吗?
    • @Potatoswatter:我再次重复“我可以改变我的设计,这很容易,但我想发现这个问题的技术方面,因为它很有意义”
    猜你喜欢
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    • 2018-04-22
    相关资源
    最近更新 更多