在使用转换构造函数编译代码时,为什么需要const复制构造函数?

时间:2018-05-22 16:02:48

标签: c++

我在 A.h

中有这样的课程
class A {
public:
    A(int *object) {
        std::cout << "convert";
    }

    A(A &object) {
        std::cout << "copy";
    }
};

并在 main.cpp

A a = new int;

然后,当我试图编译它时,我得到了

  

从a开始无效初始化'A&amp;'类型的非const引用   'A'类型的右值

但是当我将 const 添加到复制构造函数时:

A(const A &object) {
    std::cout << "copy";
}

代码编译和&#34;转换&#34;叫做。它也适用于我删除复制构造函数。为什么会这样呢?我虽然这个例子与复制构造函数无关,因为我们不使用类A的实例来创建另一个。

2 个答案:

答案 0 :(得分:11)

因为代码的工作方式如下(前C ++ 17):

A a(A(new int));

注意,调用A的复制构造函数时,临时对象由于A(new int)而被创建。并且您不能将非常量左值引用绑定到临时值。

请注意,在C ++ 17中,由于保证了copy-elision,这段代码将被编译(在C ++ 17的情况下,这段代码在语义上等同于A a(new int)。你也赢了“t = t见copy打印(因为复制省略不会被调用)

答案 1 :(得分:9)

A a = new int;是复制初始化。它采用右侧的内容并使用它来初始化左侧的内容作为副本。因为new int不是A,所以编译器会调用转换构造函数。临时不能绑定到非const引用,因此您会收到错误。当您添加const时,您现在可以将临时绑定到它,它将起作用。删除复制构造函数也很有用,因为编译器会为您提供一个,并且它会在const引用中提供一个,