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_
未初始化。正确编写这样一个类的常见做法是什么?
答案 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
成员成为指针或自动变量。