考虑以下代码:
#include<iostream>
using namespace std;
class A{
public:
A()=default;
A(int a){cout<<"A(int) called"<<endl;}
A(const A&a);
~A(){cout<<"~A() called"<<endl;}
};
A::A(const A&a){
cout<<"A(const A&) called"<<endl;
}
int main(){
A a = 1;
}
当我使用 g++8.1 编译-fno-elide-constructors
取消 RVO 时,输出为:
A(int) called
A(const A&) called
~A() called
~A() called
我知道这是一种叫做转换构造函数的东西,一种从其参数类型到其类类型的隐式转换。
似乎首先一个临时对象是由 构造的A(int)
,其次是a
对象是由复制构造函数构造的A(const A&)
。
但是当我修改我的代码时:
#include<iostream>
using namespace std;
class A{
public:
A()=default;
A(int a){cout<<"A(int) called"<<endl;}
explicit A(const A&a); //use explicit
~A(){cout<<"~A() called"<<endl;}
};
A::A(const A&a){
cout<<"A(const A&) called"<<endl;
}
int main(){
//A a = A(1); //error:no constructor match
A b = 1; //ok
}
对象是显式b
复制构造的,这让我很困惑?!即使我使用复制初始化?
当我删除复制构造函数时,它不会按预期工作。A(const A&a)=delete;
但是,当我使用 VS2017 时,情况就不同了。隐式转换A a = 1;
与复制构造函数无关。即使我删除了 cc,它也照常工作。