假设我有 A 类:
class A {
int i;
public:
A(){};
A(int i){this->i=i;};
};
还有一个简单的测试函数:
void test(const A &a){...}
现在,如果我这样做:
int main()
{
test(2);
}
它会编译并调用 A(int i)
构造函数。但是当我将参数更改为非常量时:void test(A &a)
我收到编译错误。
这些情况之间有什么区别,为什么允许第一种情况而不允许第二种情况,以及在第一种情况的初始化中实际发生了什么?
这两种情况的区别在于,允许 C++ 编译器创建临时对象以传递给接受 const
引用的函数,但函数接受非 const
引用必须提供实物。
当你调用 test(2)
时实际发生的是这样的:
A hidden(2);
test(hidden);
编译器创建隐藏
对象,用2
初始化它,并将结果传递给test
。因为 test
保证不会修改 A
,所以这没问题。
当 test
不提供这样的保证时:想象 test
设置一个新值:
void test(A& a) {
a.i++; // let's pretend "i" is public
}
如果您使用实际对象调用 test
,即 A a(3); test(a);
您可以在 test
返回后从 a
中获取更新结果。另一方面,调用 test(2)
使您无法访问更新结果。这表明逻辑中存在潜在错误,因此编译器将其视为错误。