12

考虑以下代码 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]

为什么编译器不直接调用构造函数?

4

2 回答 2

23

那是因为引用只能在初始化列表中初始化。采用

Test (int &x) : t(x) {}

解释一下:引用只能设置一次,发生这种情况的地方就是初始化列表。完成后,您不能设置引用,而只能为引用的实例分配值。您的代码意味着,您尝试将某些内容分配给引用的实例,但该引用从未初始化,因此它没有引用任何实例int并且您收到错误。

于 2013-03-14T07:53:08.783 回答
3

我的编译器发出此错误:

错误 C2758:“Test::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;
}

解释:

如果引用不在初始化器列表中,编译器几乎不可能检测到引用是否已初始化。必须初始化引用。想象一下这个场景:

Test (int &x, bool b) 
{
   if( b ) t = x;
}

现在由构造函数的调用者来决定是否生成了有效的代码。那不可能。编译器必须确保在编译时初始化引用。

于 2013-03-14T07:56:25.133 回答