Ank*_*wah 15 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;
}
Run Code Online (Sandbox Code Playgroud)
我为此使用了g ++编译器.它调用构造函数而不是复制构造函数.它应该调用复制构造函数,因为我正在创建一个对象来创建另一个对象?这里有什么问题,标准说了什么?
son*_*yao 17
由于复制省略,这里省略了复制结构.从C++ 17可以保证这种行为.在C++ 17之前,它不是强制性的; 允许编译器,但不要求执行复制省略1.
在下列情况下,编译器需要省略类对象的复制和移动构造,即使复制/移动构造函数和析构函数具有可观察到的副作用.它们不需要存在或可访问,因为语言规则确保不会发生复制/移动操作,甚至在概念上:
在初始化中,如果初始化表达式是prvalue且源类型的cv-nonqualified版本与目标类相同,则初始化表达式用于初始化目标对象:
Run Code Online (Sandbox Code Playgroud)T x = T(T(T())); // only one call to default constructor of T, to initialize x
这意味着,mango将由默认构造函数直接初始化.
[1]事实上,大多数实现也会在C++ 17之前执行复制省略.使用Gcc,您可以尝试使用-fno-elide-constructorspre-C++ 17模式中的选项来禁用复制省略.