【问题标题】:assignment operator by value not compiling with explicit copy constructor按值赋值运算符不使用显式复制构造函数编译
【发布时间】:2014-10-28 15:44:12
【问题描述】:

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

如下定义,使用“显式”,赋值代码将无法编译。 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;
}

赋值运算符(按值传递)强制使用复制构造函数,但是使用显式时无法找到完美匹配。那么当显式被移除时,编译器会执行哪些转换,我该如何编写匹配的复制构造函数?

【问题讨论】:

  • 我不太明白你在问什么,你似乎已经发现了问题......
  • 复制构造函数不应该是显式的。
  • 您的赋值运算符是否在进行复制和交换或类似操作?否则它将采用 const 引用。
  • @T.C.为什么 Copy 构造函数不应该是显式的,什么是合理的?

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


【解决方案1】:

任务

tempCat = tempCat3

通过重载解析进行调查并重写为

tempCat.operator=(tempCat3)

重载解析现在寻找匹配的成员函数来调用。它会找到你的复制赋值运算符:

CCat& operator=( CCat oldCat )

参数oldCat 必须使用参数tempCat3 进行初始化。正确的说法其实是copy-initialization

表单中发生的初始化

T x = b;

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

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

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

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

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

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

如果explicit 被删除,初始化工作正常。

【讨论】:

  • 你今天肯定增加了我的知识。我在哪里可以找到有关编译器在传递源代码时采取的步骤的更多一般信息,例如。正如你上面解释的那样?另外我不明白为什么“复制初始化仅适用于非显式构造函数”我错过了什么?
猜你喜欢
  • 1970-01-01
  • 2011-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-28
  • 2013-04-13
  • 2014-10-12
相关资源
最近更新 更多