【问题标题】:Initializing reference member variable with literal用文字初始化引用成员变量
【发布时间】:2014-01-31 13:38:56
【问题描述】:

在下面的代码中,我用文字初始化了一个引用变量。

class ABC
{
  public:
     const int& a;
     ABC():a(43) { }
     void newfoo()
     {
           printf("NEWFOO %d",a);
     }
};
int main()
{
   ABC obj;
   obj.newfoo();
}

这个程序的输出是NEWFOO 32767,当我知道以下代码可以正常工作时,这似乎不合逻辑。

int main()
{ 
  const int& b=3;
  printf("%d",b);
}

这里发生了什么?如果编译器在引用变量的初始化过程中声明了一些临时变量,那么该变量的范围不是在 main 内,因为该类在全局范围内吗?

【问题讨论】:

  • 不要用文字初始化成员引用。我相信这是未定义的行为。
  • 为什么要这样标准化?让这个编译没有意义。

标签: c++ variables reference initialization


【解决方案1】:

clang 对此代码产生以下警告,即使没有任何标志 (see it live):

warning: binding reference member 'a' to a temporary value [-Wdangling-field]
 ABC():a(43) { }
         ^~

另一方面,gcc 需要-Wall-Wextra

如果我们查看this reference initialization reference,它会说:

临时绑定到构造函数初始化器列表中的引用成员只会持续到构造函数退出,而不是只要对象存在。

这可以在草案 C++ 标准部分12.2 临时对象5 段中找到,其中包括以下项目符号

— 在构造函数的 ctor-initializer (12.6.2) 中,临时绑定到引用成员会一直存在,直到构造函数退出。

【讨论】:

    【解决方案2】:

    将创建一个临时对象并将引用绑定到该临时对象 (C++03 8.5.3.5)。临时对象将在构造函数调用结束时被销毁,留下一个悬空引用。这是在 C++03 12.2.5 中指定的:

    在构造函数的 ctor-initializer (12.6.2) 中临时绑定到引用成员会一直存在,直到构造函数退出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 2021-03-12
      • 2012-08-23
      • 2014-09-08
      • 2020-09-20
      相关资源
      最近更新 更多