为什么不调用复制构造函数

时间:2013-01-04 09:21:17

标签: c++

  

可能重复:
  What are copy elision and return value optimization?

我很难理解为什么在下面的代码中没有调用复制构造函数。

#include <iostream>

class Test
{
public:
  Test(int){std::cout << "Test()" << std::endl;}
  Test(const Test&){std::cout << "Test(const Test&)" << std::endl;}
};

int main()
{
  // Test test;
  Test test2(Test(3));

  return 0;
}

有人可以解释为什么只调用构造函数而没有复制构造函数吗? 感谢。

3 个答案:

答案 0 :(得分:24)

这称为 copy elision 允许编译器进行此优化。虽然标准无法保证,但任何商业编译器都会尽可能地执行此优化。


标准参考

C ++ 03 12.8.15:

  

[...]复制操作的省略是   允许以下内容   情况(可以合并   消除多份副本):

     

[...]

     
      
  • 当一个临时类对象有   没有受到参考(12.2)   将被复制到一个类对象   相同的cv-unqualified类型,副本   操作可以省略   构造临时对象   直接进入了目标   省略副本
  •   

您可以使用一些编译器设置来禁用此优化,例如gcc,来自 man page

-fno-elide-constructor
  

C ++标准允许实现省略创建临时文件,该临时文件仅用于初始化相同类型的另一个对象。指定此选项会禁用该优化,并且   迫使G ++在所有情况下调用复制构造函数。

但是,使用它会使您的代码在不同的编译器中不可移植。

答案 1 :(得分:11)

这是因为您的编译器执行了优化。编译器允许执行此类优化,但它不是要求,因此保证。

请注意,尽管最终未调用复制构造函数,但语义上 可访问。也就是说,如果你创建了复制构造函数private,你的代码将编译!!这是因为语义检查在优化阶段之前完成,这意味着编译器首先检查复制构造函数是否可访问; 如果 可访问,那么只会出现复制构造被省略的优化阶段。

答案 2 :(得分:0)

正如其他人已经提到的那样,这是因为编译器的优化。

我还没有检查过它,但是您可能可以使用优化编译代码,而不需要查看汇编程序代码。那么你也应该定义一些差异。