所以我正在学习构造函数初始化列表,我写了以下代码:
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/