在下面的代码中,我用文字初始化一个引用变量。
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中,因为该类在全局范围内?
答案 0 :(得分:2)
将创建一个临时文件,并将引用绑定到该临时文件(C ++ 03 8.5.3.5)。临时将在构造函数调用结束时销毁,留下悬空引用。这在C ++ 03 12.2.5中指定:
构造函数的ctor-initializer(12.6.2)中的引用成员的临时绑定将持续存在,直到构造函数退出。
答案 1 :(得分:2)
即使没有任何标记( see it live ),clang
也会为此代码生成以下警告:
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)中的引用成员的临时绑定将持续存在,直到构造函数退出。