在构造函数中引用未初始化的对象

时间:2010-10-22 12:42:01

标签: c++ constructor reference initialization

可以将未初始化的对象传递给父类,如下例所示

class C
{
    public:
        C(int i): 
            m_i(i)
        {};

        int m_i;
}

class T
{
    public:
        T(C & c):
            m_c(c)
        {
        };

        C & m_c;
};


class ST : public T
{
    public:
        ST():
            T(m_ci),
            m_ci(999)
        {
        };

        C m_ci;
};

class T构造函数中,c是对未初始化对象的引用。如果class T在构造期间使用c对象,则可能会导致错误。但由于它不是,这编译并正常工作。我的问题是 - 它是否会制定某种范式或良好的设计指令?如果是这样,有什么选择,因为我发现在子类中分配父对象所需的对象很有用。

在旁注中,我想知道为什么不可能更改初始化顺序,以便在初始化某些成员之后调用基类构造函数。

3 个答案:

答案 0 :(得分:3)

将引用或指针传递给未初始化的内容在技术上完全没问题。

但你问的原因可能是你认为容易出错的事情,通过一些调用链可能会在初始化之前无意中访问该对象。我认为这是一个有效的问题。还有一件事可能出错,即基类T中的代码现在可能通过直接更改ST实例的数据成员来使ST的类不变量无效... < / p>

所以,我认为这有点风险。

关于初始化顺序,C ++基于在层次结构中从部分构建的思想。如果构造函数抛出,那么完全构造的东西会被自动破坏。对于更随意的施工顺序,这将更加困难或效率更低。

干杯&amp;第h。,

答案 1 :(得分:2)

我已经看过很多了,许多编译器都会发出警告。如果T构造函数从不取消引用c引用,那就没关系。

如果您不想要警告,则需要进行两阶段构建。在Init(C&)中创建一个受保护的T方法,然后在ST构造函数体中调用它 - 遗憾的是m_c需要指针来执行此操作(因为引用可以不能重新分配到另一个对象)

答案 2 :(得分:1)

可以,但您会得到未定义的行为。

在Boost的实用程序中,您会找到由base-from-member idiom创建的R. Samuel Klatchko。基本上,你在私人会员的位置建立私人基地。此基础首先被初始化,您可以将其用于其他基础:

// ...

class C_base
{
public:
    C_base(int i) :
    m_ci(i)
    {}

    C m_ci;
};


class ST :
    private C_base
    public T
{
    public:
        ST() :
            C_base(999),
            T(m_ci),
        {
        };
};

Boost的实用程序消除了重复的代码。