赋值运算符的值不使用显式复制构造函数进行编译

时间:2014-10-28 15:44:12

标签: c++ copy-constructor assignment-operator

我想了解在显式复制构造函数中应该使用哪些正确的参数类型。

如下所述,使用“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时,编译器执行哪些转换以及如何编写匹配的复制构造函数?

1 个答案:

答案 0 :(得分:1)

作业

tempCat = tempCat3
通过重载决策调查

并重写为

tempCat.operator=(tempCat3)

重载解析现在查找要调用的匹配成员函数。它找到了你的副本赋值运算符:

CCat& operator=( CCat oldCat )

必须使用参数oldCat初始化参数tempCat3。正确的术语实际上是复制初始化

  

形式出现的初始化
T x = b;
     

以及在参数传递中,[...] 称为复制初始化

复制初始化仅适用于非显式构造函数:

  

对于复制初始化,候选函数都是   转换该类的构造函数(12.3.1)。

(也称为转换构造函数):

  

在没有函数说明符explicit的情况下声明的构造函数   指定从其参数类型到类型的转换   它的班级。这样的构造函数称为转换构造函数

因此,如果您将复制构造函数声明为const - 引用参数为explicit,则它不是转换构造函数,复制初始化不起作用且参数无法使用参数 - 这也是编译器告诉我们的,没有找到匹配的构造函数。
这同样适用于main中的其他行。

如果删除explicit,初始化就可以了。