代码段1:
#include<iostream>
using namespace std;
class C{
public:
C(){}
C(const C& c){
cout<<"const copy constructor called"<<endl;
}
};
int main(){
C c1;
C c2 = c1;
return 0;
}
输出:调用const复制构造函数
片段2:
#include<iostream>
using namespace std;
class C{
public:
C(){}
C(const C& c){
cout<<"const copy constructor called"<<endl;
}
C(C& c){
cout<<"non-const copy constructor called.\t "<<endl;
}
};
int main(){
C c1;
C c2 = c1;
return 0;
}
输出:称为非常量复制构造函数
片段3:
#include<iostream>
using namespace std;
class C{
public:
C(){}
C(const C& c){
cout<<"const copy constructor called"<<endl;
}
C(C c){
cout<<"non-const copy constructor called.\t "<<endl;
}
};
int main(){
C c1;
C c2 = c1;
return 0;
}
输出:错误:复制构造函数必须通过引用传递其第一个参数
我很困惑:
片段2的
C(const C& c)
,C(C c)
不会引起无限递归,为什么它仍然不起作用? 最佳答案
代码段1 :一个带有const T&
的标准拷贝构造函数。快乐的世界。
代码段2 :
有效完成的工作是使复制构造函数过载-一个使用引用T&
的拷贝构造函数,而另一个使用一个恒定引用const T&
的拷贝构造函数。
请注意:类T的任何构造函数具有一个必需的T &
或const T &
类型的参数(它可能还具有其他默认参数)是复制构造函数。
因此,对于编译器而言,一切都归结为找到用于过载解析的最适合,它的完成方式是:
所以写
C c1;
C c2 = c1;
会调用非const复制构造函数,因为它是更好的匹配,但是,
写作,
const C c1;
C c2 = c1;
将调用const复制构造函数(您可以检查),因为现在带有const的复制构造函数是唯一可行的匹配项。
片段3对于编译器来说是完全错误的。
C(C c){
cout<<"non-const copy constructor called.\t "<<endl;
}
您不能使用带有签名
C(C c)
的方法。编译器认为您正在尝试编写一个拷贝构造函数而错过了写&
的操作,因此报告了错误。删除它,它工作正常。@除非您有充分的理由,否则永远不要将
C(C& c)
用作拷贝构造函数。不要跳过const
,因为对从中进行复制的对象进行更改没有多大意义。