Gil*_*Gil 0 c++ constructor type-conversion copy-constructor
我有以下C ++代码(VS2013):
#include <iostream>
using namespace std;
class A {
int i;
public:
A(int i) : i(i) {
cout << "Constructor: " << i << endl;
}
A(const A &o) : i(o.i) {
cout << "Copy constructor: " << i << endl;
}
~A() {
cout << "Destructor: " << i << endl;
}
};
A test(const A &a, A b, A *c) {
return *c;
}
int main() {
A b(10);
cout << "START OF TEST" << endl;
test(1, b, &b);
cout << "END OF TEST" << endl;
system("pause");
}
Run Code Online (Sandbox Code Playgroud)
运行代码时,在“测试开始”和“测试结束”输出之间得到以下输出:
构造函数:1
复制构造函数:10
复制构造函数:10
毁灭者:10
毁灭者:10
析构函数:1
构建3个对象:1个使用整数1,2个使用类对象A(i = 10)。
值得一提的是,当test函数的参数const A &a更改为A &a(不是常量)时,程序将无法编译,并出现以下错误:
错误C2664:'A test(A&,A,A *)':无法将参数1从'int'转换为'A&'
如何解释这种行为?
特别:
为什么发送整数1以test使A的参数构造函数A(int i)起作用(并且仅在const使用时)?
为什么A的副本构造函数A(const A&o)工作两次?(调用时会发生一次运行test,返回时会发生另一种运行*c)。
好吧,test使用第一个参数调用1会导致创建rvaluetype类型A。可以将右值分配给,const lvalue reference 但不能分配给普通lvalue引用。如果要不使用它进行编译,const则必须指定该参数为rvalue引用。
g++ 错误信息更多:
error: cannot bind non-const lvalue reference of type ‘A&’ to an rvalue of type ‘A’
test(A(1), b, &b);
Run Code Online (Sandbox Code Playgroud)
rvalue可以分配给rvalue reference或 lvalue reference to const。这是为什么? rvalues是临时对象或文字。如果此代码合法
int &r = 5
那么您将能够进行修改5。另一方面,lvalue references to const禁止对其引用的对象进行任何更改,因此您可以将它们绑定到rvalue。
const A& x = 1; //compile
x = 2; //error!
A&& xxx = 1; //compile
A& xx = 1; //does not compile.
Run Code Online (Sandbox Code Playgroud)
关于第二个问题。您正在A从中返回的副本,test因此*c会触发的副本的构建c。尝试A从中返回引用,test以查看未调用构造函数。