片段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;
}
输出:错误:复制构造函数必须通过引用传递其第一个参数
我很困惑:
C(const C& c)
,C(C c)
不会导致无限递归,为什么它仍然不起作用?片段1:一个带有的标准副本构造函数const T&
。快乐的世界。
片段2:
有效完成的工作是使复制构造函数重载-一个使用引用T&
,而另一个使用常量引用const T&
。
请注意:类T的任何构造函数具有一个类型为(T &
或const T &
也可以具有其他默认参数)强制类型的复制构造函数。
因此,对于编译器来说,一切都归结为找到最适合过载解析的方法,它的完成方式如下:
在以下情况下,标准转换序列S1比标准转换序列S2是更好的转换序列:
- ....
- S1和S2是引用绑定(8.5.3),除了顶级cv限定符之外,引用所引用的类型是相同的类型,并且由S2初始化的引用所引用的类型比cv限定的类型更多。 S1初始化的引用所引用的类型。
所以写
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
因为要更改要从中复制对象的对象没有多大意义。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句