考虑下面的代码C ++:
#include<iostream>
using namespace std;
class Test {
int &t;
public:
Test (int &x) { t = x; }
int getT() { return t; }
};
int main()
{
int x = 20;
Test t1(x);
cout << t1.getT() << " ";
x = 30;
cout << t1.getT() << endl;
return 0;
}
它示出了在使用gcc编译以下错误
est.cpp: In constructor ‘Test::Test(int&)’:
est.cpp:8:5: error: uninitialized reference member ‘Test::t’ [-fpermissive]
为什么不直接编译调用构造函数?
这是因为引用只能在初始化列表中进行初始化。 使用
Test (int &x) : t(x) {}
讲解:参考只能设置一次,在发生这种情况的地方就是初始化列表。 做到这一点后,你可以不设置参考,但只分配值所引用的实例。 您的代码意味着,你想的东西分配给一个参考实例,但参考从未被初始化,因此它不会引用的任何实例int
和你的错误。
我的编译器生成此错误:
错误C2758:“测试:: T”:必须构造基/成员初始化列表初始化
而这正是你必须做什么。 引用必须在初始化列表中进行初始化:
#include<iostream>
using namespace std;
class Test {
int &t;
public:
Test (int &x) : t(x) { } // <-- initializer list used, empty body now
int getT() { return t; }
};
int main()
{
int x = 20;
Test t1(x);
cout << t1.getT() << " ";
x = 30;
cout << t1.getT() << endl;
return 0;
}
说明:
如果参考不在initiliazer名单,这是几乎不可能的,如果参考初始化编译器来检测。 参考文献必须初始化。 想象一下这样的场景:
Test (int &x, bool b)
{
if( b ) t = x;
}
现在,它要由构造函数的调用,以决定是否生成有效的代码。 那是不可能的。 编译器必须确保引用在编译时被初始化。