面试官向我展示了这样的代码并问我是否会编译,并给出我的推理。我非常肯定地告诉他,它不会编译,因为10是一个常量,你不能为非const引用分配一个常量(比如int& b = 10将不会编译),同样,_a是一个临时变量,它是同样也考虑了const,你不能使用非const引用来引用一个const变量。
然而,在我惊讶地回到家后,我发现它与所有可能的编译器完美编译。而且,我没有得到这份工作。我理解的哪一部分出了问题?
class A {
int& a;
public:
A(int _a):a(_a) {}
};
int main() {
A a(10);
}
答案 0 :(得分:27)
使用此代码没有const的“赋值”...
代码调用构造函数,该构造函数接受int
并依次调用int&
的初始值设定项。当您认为int& b = 10
更像_a = 10; int& a = _a;
时,您跳过编译器看到/采取的几个步骤。它编译但是你想要使用什么都没有(绑定对栈的引用,以后会导致未定义的行为/损坏)......
答案 1 :(得分:12)
_a是一个临时变量,它也被认为是const,
错误。在构造函数体和初始化列表的范围内,它根本不是临时的。它是一个左值和函数参数 - 它超出了你对单个用途的所有功能。
此外,rvalues和const
完全没有任何关系,除了在C ++ 03中你不能将非const引用绑定到rvalues。例如,你可以在rvalues上调用大量的非const函数。
此代码直接等同于
int main() {
int i = 10;
int& x = i;
}
随着课堂上涉及的终身问题的增加乐趣。
答案 2 :(得分:7)
这将绑定到堆栈,因为函数参数可以通过引用绑定。然而,这根本不安全,并且会在某些时候导致未定义的行为和堆栈损坏。
答案 3 :(得分:4)
这个问题有两个问题。
q1)是否应该编译?
Ans:它会编译,因为这里 a引用_a ,编译器头疼的方式是_a将如何获取数据。
q2)这是正确的代码吗?我是说是否会出现运行时错误?
Ans:这不是正确的代码。这里 a指_a是堆栈变量。因此,如果您使用类A对象访问变量a,则输出将是不可预测的。 让我们举个例子如下:
class A {
public:
int& a;
A(int _a):a(_a) {}
};
int main() {
A a(10);
A a1(11);
cout << a.a;
}
请参阅output.Output是不可预测的,因为您正在尝试访问引用构造函数的堆栈变量的引用变量