考虑以下代码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]
为什么编译器不直接调用构造函数?
答案 0 :(得分:19)
这是因为只能在初始化列表中初始化引用。使用
Test (int &x) : t(x) {}
解释:引用只能设置一次,发生这种情况的地方是初始化列表。完成此操作后,您无法设置引用,只能为引用的实例分配值。您的代码意味着,您尝试将某些内容分配给引用的实例,但引用从未初始化,因此它不引用int
的任何实例,并且您得到错误。
答案 1 :(得分:2)
我的编译器发出此错误:
错误C2758:'Test :: t':必须在构造函数base / member initializer list中初始化
这正是你必须做的。引用必须在初始化列表中初始化:
#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;
}
现在由构造函数的调用者来决定是否生成了有效的代码。那不可能。编译器必须确保在编译时初始化引用。