C++样式的构造函数调用

J B*_*ble 3 c++ constructor initialization language-lawyer

我有一个名为的对象Thing,它的构造函数接受一个int.

此代码按预期工作:

Thing thing(5);

然而,偶然我写了以下内容:

Thing thing = Thing(5); // note: no 'new'

并得到了错误no matching constructor for initialization of 'Thing'.后一个代码的实际含义是什么?我知道如果我扔new在那里意味着什么,但没有新的,这是什么意思?

rom*_*m1v 10

Thing thing = Thing(5);
Run Code Online (Sandbox Code Playgroud)

需要定义(非explicit)复制(或移动) - 构造函数:

Thing(const Thing &);
Run Code Online (Sandbox Code Playgroud)

(即使没有出于优化原因而调用它).

  • @ P0W,因为`Thing thing(5);`有效,至少有一个构造函数`Thing(int)`(`explicit`或不是).如果`Thing thing = Thing(5)`不起作用,IMO我们可以断定副本(/ move) - 构造函数丢失了.你能提供一个反例吗? (2认同)

son*_*yao 9

Thing thing(5);直接初始化,thing由apporiate构造函数(即Thing::Thing(int))直接构造.

Thing thing = Thing(5);复制初始化,这与直接初始化不完全相同.但是对于这种情况,从C++ 17开始,它也将Thing::Thing(int)直接调用构造对象,然后它与直接初始化具有相同的效果.

首先,如果T是一个类类型,并且初始化程序是一个prvalue表达式,其cv-unqualified类型与它是同一个类T,则初始化程序表达式本身,而不是从中实现的临时表达式,用于初始化目标对象:请参阅copy elision

在C++ 17之前,第二种情况(即复制初始化)要求复制/移动构造函数是可访问和非显式的; 如果是这种情况并且您使用的编译器不支持C++ 17,则会导致错误.

如果T是一个类类型和类型的CV-不合格版本otherIS T或从派生的类T的非显式的构造T进行检查和最佳匹配是由过载分辨率来选择.然后调用构造函数来初始化对象.

请注意,从C++ 17开始,代码编译正常.根据复制省略规则,复制/移动构造函数不需要是可访问的,explicit对于这种情况.

在下列情况下,编译器需要省略类对象的复制和移动构造函数,即使复制/移动构造函数和析构函数具有可观察的副作用:

  • 在初始化中,如果初始化表达式是prvalue且源类型的cv-nonqualified版本与目标类相同,则初始化表达式用于初始化目标对象:

    T x = T(T(T())); // only one call to default constructor of T, to initialize x
    
    Run Code Online (Sandbox Code Playgroud)