我想了解在显式复制构造函数中应该使用哪些正确的参数类型。
如下所述,使用“explicit”,分配代码将无法编译。 main中的赋值行生成错误:'没有匹配的构造函数用于初始化CCat'
从第一个拷贝构造函数中删除“显式”修复了问题,但我不明白为什么。
编译器显然正在进行一些微妙的隐式转换?
class CCat : public CAnimal
{
public:
explicit CCat( string name, uint noLegs, bool fur, bool domestic, string breed );
explicit CCat( const CCat& oldCat ) : CAnimal( oldCat )
{
std::cout << "\nCCat::CCat( const CCat& oldCat ) \n";
}
explicit CCat( CCat& oldCat ) : CAnimal( oldCat )
{
std::cout << "\nexplicit CCat::CCat( CCat& oldCat ) \n";
}
~CCat();
CCat& operator =( CCat oldCat ){
//.. do assignment stuff
return *this;
}
};
int main(int argc, const char * argv[])
{
CCat *cat1 = new CCat( string("Wiggy"), 4, true, true, string("Tabby") );
CCat *cat2 = new CCat( string("Tibles"), 4, true, true, string("Tom") );
CCat tempCat( *cat1 );
CCat tempCat2( *cat2 );
std::cout << "CCat tempCat2( *cat2 );\n";
const CCat& tempCat3 = *cat2;
tempCat = tempCat3; // will not compile without explicit removed from first C/Constr
tempCat = CCat(*cat2); // will not compile without explicit removed from first C/Constr
tempCat = tempCat2; // will not compile without explicit removed from first C/Constr
return 0;
}
赋值运算符(按值传递)强制使用复制构造函数,但是在使用explicit时无法找到完美匹配。因此,当删除explicit时,编译器执行哪些转换以及如何编写匹配的复制构造函数?
答案 0 :(得分:1)
作业
tempCat = tempCat3
通过重载决策调查并重写为
tempCat.operator=(tempCat3)
重载解析现在查找要调用的匹配成员函数。它找到了你的副本赋值运算符:
CCat& operator=( CCat oldCat )
必须使用参数oldCat
初始化参数tempCat3
。正确的术语实际上是复制初始化。
以
形式出现的初始化T x = b;
以及在参数传递中,[...] 称为复制初始化。
复制初始化仅适用于非显式构造函数:
对于复制初始化,候选函数都是 转换该类的构造函数(12.3.1)。
(也称为转换构造函数):
在没有函数说明符
explicit
的情况下声明的构造函数 指定从其参数类型到类型的转换 它的班级。这样的构造函数称为转换构造函数。
因此,如果您将复制构造函数声明为const
- 引用参数为explicit
,则它不是转换构造函数,复制初始化不起作用且参数无法使用参数 - 这也是编译器告诉我们的,没有找到匹配的构造函数。
这同样适用于main
中的其他行。
如果删除explicit
,初始化就可以了。