正确初始化成员引用

时间:2010-12-13 15:10:42

标签: c++ constructor

class Temp {
    public : 
        Temp(X& x): x_(x) {}
        Temp(X& x, Y& y) : x_(x), y_(y) {}
        ...
    private:
        X& x_;
        Y& y_;
}

我收到了错误,因为如果Temp(X& x): x_(x),则引用y_未初始化。正确编写这样一个类的常见做法是什么?

6 个答案:

答案 0 :(得分:11)

我会建议另一种方法,即使这可能不是你想要的。

它不使用引用变量(代替内存指针),它也不使用boost,但它允许你保留两个构造函数而不需要花费更多的内存资源。

#include <iostream>

class Temp
{
    public :
        Temp(int& x): x_(&x), y_(NULL) {}
        Temp(int& x, int& y) : x_(&x), y_(&y) {}
        void print() { std::cout << "*x_: " << *x_ << std::endl; }

    private:
        int* x_;
        int* y_;
};

int main()
{
    int x = 5;
    Temp tmp(x);

    tmp.print();

    return 0;
}

答案 1 :(得分:10)

您不能拥有未初始化的参考成员!如果是这种情况,请考虑将引用包装在boost::optional中,然后您可以选择构造引用。

编辑:这是boost::optional方法......

class Temp {
    public : 
        Temp(X& x): x_(x) {}
        Temp(X& x, Y& y) : x_(x), y_(y) {}
        ...
    private:
        X& x_;
        boost::optional<Y&> y_; // by default this is constructed with none_t
}

答案 2 :(得分:7)

拥有作为参考的数据成员是 STRONG合同: 这意味着您不能拥有nullptr或未定义的对象,您的类需要此对象,该对象需要存在。

因此,您的第一个构造函数违反了这个强大的合同,因此无法编译。

正如karlphillip建议的那样:你应该使用指针,因为你不想尊重这样的合同,以确保始终定义_y。

如果你的类在没有引用对象预先存在的情况下没有意义,那么将引用作为成员是有效的。

答案 3 :(得分:1)

老实说,通常的做法是不使用引用作为结构或类的数据成员。

为什么你认为你想这样做?从概念上讲,引用是已存在事物的另一个名称。物体就是物体。你应该能够用整块布制作它们。有时他们会将指针(或某些智能指针类的实例)指向已经存在的其他东西,但至少指针本身就是真实数据。

答案 4 :(得分:1)

您对y_有参考!引用必须初始化,而您的第一个构造函数不会。如果在创建类时无法绑定到y,则应该使用指针。

答案 5 :(得分:0)

消除第一个构造函数或消除第二个引用。如果您有参考,那么您必须立即初始化它。如果必须提供默认初始化Y成员的构造函数,则使Y成员成为指针或自动变量。