如何初始化一个类的引用成员变量?

Posted

技术标签:

【中文标题】如何初始化一个类的引用成员变量?【英文标题】:How to initialize the reference member variable of a class? 【发布时间】:2013-03-14 07:51:42 【问题描述】:

考虑下面的 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]

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

【问题讨论】:

虽然答案解释了如何解决这个问题,但我想指出根本问题是初始化实际上发生在 输入构造函数的主体之前,以确保所有成员在使用前都处于有效状态。由于引用必须被初始化,并且在初始化后不能被“重新定位”,所以在输入构造函数的主体之前,它们在逻辑上也需要指向一个实际的变量。 【参考方案1】:

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

Test (int &x) : t(x) 

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

【讨论】:

它们也可以通过 brace-or-equal-initializer 进行初始化,尽管这是一个不常见的用例 如果你需要一个默认的Test构造函数,你会怎么做? @TomAuger 在类(或其他地方)中添加一个静态虚拟 int 并将引用绑定到它。【参考方案2】:

我的编译器发出此错误:

错误 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;

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

【讨论】:

更不用说t = x不是引用初始化的事实。这是一个任务。对于引用,它们非常不同:初始化将引用绑定到一个对象,赋值分配到引用绑定到的对象中。

以上是关于如何初始化一个类的引用成员变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何初始化类的static成员变量?

JAVA中的成员变量不赋值默认是0吗?

如何创建一个不可变类

如何创建一个不可变类

如何初始化作为另一个类的成员变量的基类对象?

如何在 C++ 子类的构造函数中初始化超类的 const 成员变量?