【问题标题】:Initializing non const reference with integer value用整数值初始化非常量引用
【发布时间】:2018-02-08 17:27:17
【问题描述】:

请考虑以下代码:

#include <iostream>

using namespace std;

class test
{
    int& ref;
    public:
    test(int i):ref(i)
    {
        cout << "Constructor Called" << endl;
    }
    void p(){ cout<< ref << "\n";}
};

int main()
{
    test obj(5);
    obj.p();

    return 0;
}

输出:

Constructor Called
5

疑问: 此处如何使用整数值 (5) 初始化非常量引用 (ref),而以下代码失败:

int& r = 5;

【问题讨论】:

  • 它不是用 5 初始化的,而是用i 初始化的。对p() 的调用是UB。
  • GCC 7.2 在我尝试编译时给了我一个警告:“警告:将引用成员 'ref' 绑定到堆栈分配的参数 'i' [-Wdangling-field]”。
  • ref(i)i 初始化ref,这是一个在test 返回时将被销毁的本地参数,给您留下一个悬空引用。
  • 之前,更正,编译器是 Clang 5.0

标签: c++ reference


【解决方案1】:

test's构造函数:

test(int i)

int 作为参数按值

当您通过将5 传递给其构造函数来初始化obj 对象时,即:

test obj(5);

那个构造函数的参数i被设置为5(即:5被复制到i),然后在构造函数成员初始化列表中用这个参数初始化成员引用ref(而不是构造函数调用时使用的文字5):

test(int i):ref(i)

您有一个危险的引用:引用 ref 比被引用对象 (i) 的寿命更长,因为一旦构造函数返回,构造函数的参数 i 就不再存在。

【讨论】:

    【解决方案2】:

    引用不是直接用5初始化的,而是用本地的i初始化的。因为i 在构造函数退出时被销毁,所以你会留下一个dangling reference,它是一个引用一个超出范围的对象的引用。诸如Clang 之类的编译器会告诉您这一点,并带有可能类似于以下内容的警告:

    警告:将 reference 成员 'ref' 绑定到堆栈分配的参数 'i' [-Wdangling-field]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-20
      • 1970-01-01
      • 2015-01-26
      • 1970-01-01
      相关资源
      最近更新 更多