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

Adr*_*ian 20 c++

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

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

Alo*_*ave 25

这称为复制省略.
允许编译器进行此优化.虽然标准不能保证,但任何商业编译器都会尽可能地执行此优化.


标准参考:

C++ 03 12.8.15:

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

[...]

  • 当一个未绑定到引用(12.2)的临时类对象被复制到具有相同cv-nonqualified类型的类对象时,可以通过将临时对象直接构造到省略副本的目标中来省略复制操作

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

-fno-elide-constructor
Run Code Online (Sandbox Code Playgroud)

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

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


Naw*_*waz 11

这是因为您的编译器执行了优化.允许编译器执行此类优化,但这不是必需的,因此无法保证.

请注意,即使最终未调用复制构造函数,也需要语义上对其进行访问.也就是说,如果你创建了copy-constructor private,你的代码将无法编译!这是因为语义检查在优化阶段之前完成,这意味着编译器首先检查复制构造函数是否可访问; 如果它是可访问的,那么只有优化阶段,其中复制构造被省略.