c++ - 构造函数初始值设定项列表未调用复制构造函数

标签 c++ constructor initialization language-lawyer copy-elision

所以我正在学习构造函数初始化列表,我写了以下代码:

class Mango
{
  public:

  Mango(){cout<<"Mango::ctor()";}
  Mango(const Mango& other){cout<<"Mango::copy_ctor()";}
};

class Box
{
    public:

    Box() : mango(Mango()) //**doesn't call copy constructor**
    {
    }

    Mango mango;
};

int main()
{
  Box box; 

   return 0;
}

我为此使用了 g++ 编译器。它调用构造函数而不是复制构造函数。它应该正确调用复制构造函数,因为我正在创建一个对象来创建另一个对象?这里有什么问题,标准对此有何规定?

最佳答案

因为copy elision ,这里省略了复制构造。从 C++17 保证了这种行为。在 C++17 之前,它不是强制性的;允许编译器执行复制省略1.

Under the following circumstances, the compilers are required to omit the copy- and move- construction of class objects even if the copy/move constructor and the destructor have observable side-effects. They need not be present or accessible, as the language rules ensure that no copy/move operation takes place, even conceptually:

  • In initialization, if the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object:

      T x = T(T(T())); // only one call to default constructor of T, to initialize x
    

也就是说,mango会直接被默认构造函数初始化。


[1] 事实上,大多数实现在 C++17 之前也会执行复制省略。与 Gcc您可以尝试在 pre-C++17 模式下使用 -fno-elide-constructors 选项来禁用复制省略。

关于c++ - 构造函数初始值设定项列表未调用复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50941703/

相关文章:

c++ - 在 D3D12 上获取显示器的刷新率

c++ - 根据模板枚举参数更改行为

Scala问题可选构造函数

c++ - 在 header C++ 中初始化变量

c++ - 当我在同一范围内多次初始化同名局部变量时,为什么 C++11 编译器不报错?

initialization - 如何在神经网络的 Xavier 初始化中计算扇入和扇出?

C# 通过引用将数组的一部分作为函数的参数传递

c++ - Octave - 访问 octave_value_list 中的值

java |反射获取构造函数

c++ - 在 C++ 中是否有时不调用父类(super class)的构造函数?