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

why isn't the copy constructor called

本文关键字:构造函数 复制 调用 为什么不      更新时间:2023-10-16

可能重复:
什么是拷贝省略和返回值优化?

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

#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;
}

有人能解释为什么只调用构造函数而没有复制构造函数吗
谢谢

这被称为复制省略
编译器可以进行此优化。尽管标准不能保证,但任何商业编译器都会在可能的时候执行这种优化。


标准参考

C++03 12.8.15:

[…]复制操作的省略是在以下情况下允许情况(可能结合消除多个副本(:

[…]

  • 当具有未绑定到引用(12.2(将被复制到具有同一简历不合格类型,复印件操作可以通过构造临时对象直接进入目标省略的副本

您可以使用一些编译器设置来禁用此优化,例如在gcc的情况下,从手册页:

-fno-elide-constructor

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

然而,使用它会使代码在不同的编译器之间不可移植。

这是因为编译器进行了优化。允许编译器执行此类优化,尽管这不是的要求,因此不能保证

需要注意的一点是,即使复制构造函数最终没有被调用,它在语义上也是可访问。也就是说,如果您使复制构造函数private,您的代码将不编译!!这是因为语义检查在优化阶段之前就已经完成了,这意味着编译器首先检查复制构造函数是否可访问如果它是可访问的,那么只有在优化阶段,复制构造被取消。

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

我还没有检查过,但你可能会在编译代码时进行优化,然后再不进行优化,看看汇编代码。那么你也应该清楚地看到一些差异。