C++ 为什么要编译?期待;无法将常量指定给非常量引用“;

C++ 为什么要编译?期待;无法将常量指定给非常量引用“;,c++,C++,面试官给我看了一个这样的代码,问我是否可以编译,并给出我的理由。我非常肯定地告诉他,它不会编译,因为10是一个常量,你不能将常量赋给一个非常量引用(比如int&b=10不会编译),而且,_a是一个临时变量,它也被认为是常量,同样,你不能使用非常量引用来引用常量变量 然而,当我惊讶地回到家后,我发现它可以用所有可能的编译器完美地编译。而且,我没有得到这份工作。我的理解哪一部分出错了 class A { int& a; public: A(int _a):a(_a) {} }

面试官给我看了一个这样的代码,问我是否可以编译,并给出我的理由。我非常肯定地告诉他,它不会编译,因为10是一个常量,你不能将常量赋给一个非常量引用(比如int&b=10不会编译),而且,_a是一个临时变量,它也被认为是常量,同样,你不能使用非常量引用来引用常量变量

然而,当我惊讶地回到家后,我发现它可以用所有可能的编译器完美地编译。而且,我没有得到这份工作。我的理解哪一部分出错了

class A {
    int& a;
public:
    A(int _a):a(_a) {}
};

int main() {
    A a(10);
}    
此代码中没有常量的“赋值”


代码调用构造函数,构造函数接受
int
,然后调用
int&
的初始值设定项。您跳过了编译器看到/采取的几个步骤,假设它的意思是
int&b=10
,而它更像
\u a=10;int&a=_a。它可以编译,但实际上并不是您想要使用的(将引用绑定到堆栈,这将导致未定义的行为/损坏).

这将绑定到堆栈,因为函数参数可以通过引用绑定到堆栈。但是,这一点都不安全,在某个时候会导致未定义的行为和堆栈损坏

_a是一个临时变量,也被视为常量

错。在构造函数主体和初始值设定项列表的范围内,它根本不是临时的。它是一个左值和函数参数-它的持续时间远远超过了您对整个函数体的单一使用

此外,rvalue和
const
绝对没有任何关系,只是在C++03中不能将非常量引用绑定到rvalue。例如,您可以在右值上调用大量非常量函数

此代码直接等效于

int main() {
    int i = 10;
    int& x = i;
}

还有一个有趣的问题,那就是在课堂上的生活问题。

这个问题有两个问题

q1)是否应该编译

答:它将被编译,因为这里a指的是_a,而不是编译器头痛的问题_a将如何获得数据

问题2)代码是否正确?我的意思是是否会有任何运行时错误

答:这不是正确的代码。这里a指的是作为堆栈变量的_a。所以,如果您使用类a对象访问引用变量,输出将是不可预测的。 让我们举一个如下所示的例子:

class A { 
public:
    int& a; 

    A(int _a):a(_a) {} 
}; 

int main() { 
    A a(10); 
    A a1(11); 
    cout << a.a;
}    
A类{
公众:
int&a;
A(int_A):A(_A){}
}; 
int main(){
A(10);
A a1(11);

如果你不想知道C++的每一个模糊的角落,我都会觉得面试官过于强调知道语言的晦涩角落,而不重视设计技巧和C++最佳实践。tices.@Mysticial:这是新开发人员的一个常见陷阱,因为这段代码一开始似乎可以工作,但在随机点(函数调用后)会失败。我采访的职位是“金融软件开发人员”@JohnYang我想问题更多的是针对这段代码的后果……他们刚开始的时候是“它会编译吗?”在回答“是”之后,他们会问“你觉得这个生产软件的代码怎么样”等等。。。