没有调用复制构造函数

时间:2010-11-27 14:10:03

标签: c++

考虑给定的代码

struct ABC
{
    ABC()
    {
        std::cout<<" Calling from default constructor";
    }

    ABC(const ABC &copy)
    {
        std::cout<<"Calling from copy constructor";
    }
};

int main()
{
    ABC abc = ABC();
}

我有两个问题


Q1)从复制构造函数参数声明中删除const会产生错误。为什么呢?

Q2)添加const关键字后,我没有看到对复制构造函数的调用。为什么?复制构造函数没有被调用,为什么const是必要的?


TIA

4 个答案:

答案 0 :(得分:5)

  1. 你需要const,因为你试图用一个临时的ABC()来初始化abc。因此,如果构造函数不是const,则编译器必须拒绝代码。

  2. 使它成为const之后,代码就是标准投诉,编译器可以编译它。但是,如本标准所述,允许在这种情况下优化副本,因此它会删除对复制构造函数的调用。

答案 1 :(得分:3)

  

Q1)从副本中删除const   构造函数参数声明   给出错误。为什么呢?

ABC abc = ABC();

相当于

ABC abc((ABC()));

由于您将临时文件传递给复制构造函数,因此它只能绑定到const引用,而不是非const引用。

复制构造函数可以使用非const引用(例如std::auto_ptr),但这意味着它们的使用受到更多限制。

  

Q2)添加const关键字I后   没有看到对副本的调用   构造函数。为什么?复制构造函数   没有被叫,所以为什么   const必要吗?

在给定的场景中,允许编译器优化对构造函数的冗余调用。为什么只创建一个默认对象来复制它,如果它只能单独调用默认构造函数?

但是,即使对复制构造函数的调用进行了优化,编译器也必须检查代码是否有效 - 就像复制构造没有被优化一样。

答案 2 :(得分:2)

const是必要的,因为不允许将临时绑定到非const引用。即使编译器优化了复制构造函数,也不会直到后一阶段。

C ++ 0x标准通过添加rvalue引用来解决这个问题。这将允许您将const参数删除到非const ...

ABC( ABC&& copy) 

虽然你仍然想要常规的参考拷贝构造函数......

答案 3 :(得分:1)

如果你还定义了赋值运算符,你会发现甚至没有调用它:编译器在ABC abc = ABC();中优化ABC abc;,因为它们具有相同的语义。 / p>

关于另一个疑问,G ++并没有抱怨将复制构造函数参数声明为非const(甚至不是-Wall -W -std=c++98)。无论如何都没有检查出这个标准。