我有一个叫做Thing
的对象,它的构造函数接受一个int值。构造函数调用的C++风格
此代码按预期工作:
Thing thing(5);
然而,意外我写了下面:
Thing thing = Thing(5); // note: no 'new'
,并得到了错误no matching constructor for initialization of 'Thing'
。后面的代码的实际含义是什么?我知道这是什么意思,如果我扔了new
在那里,但没有新的,这是什么意思?
我有一个叫做Thing
的对象,它的构造函数接受一个int值。构造函数调用的C++风格
此代码按预期工作:
Thing thing(5);
然而,意外我写了下面:
Thing thing = Thing(5); // note: no 'new'
,并得到了错误no matching constructor for initialization of 'Thing'
。后面的代码的实际含义是什么?我知道这是什么意思,如果我扔了new
在那里,但没有新的,这是什么意思?
Thing thing(5);
是direct initliazation,thing
由相应构造函数(即Thing::Thing(int)
)直接构建。
Thing thing = Thing(5);
是copy initialization,这与直接初始化不完全相同。但是对于这种情况,从C++ 17开始,它将直接调用Thing::Thing(int)
来构造对象,然后它在这里与直接初始化具有相同的效果。
首先,如果
T
是一个类类型和初始值设定为prvalue表达式,其CV-非限定类型是相同的类T
,初始化表达本身,而该临时从它物化,用于初始化目标对象:看到copy elision
C++ 17之前,第二情况下(即拷贝初始化)需要复制/移动的构造可访问和非显式;如果是这种情况,并且您使用的编译器不支持C++ 17,则会导致错误。
如果
T
是一个类类型和other
类型的CV-不合格版本是T
或从T
派生的类,的T
非显式的构造进行检查和最佳匹配是由过载分辨率来选择。然后调用构造函数来初始化该对象。
请注意,从C++ 17开始,代码会很好地编译。根据copy elision的规则,复制/移动构造函数不需要可访问,对于这种情况,explicit
。
在下列情况下,需要编译器省略 的复印通和类的构造函数MOVE-对象即使复制/移动 构造函数和析构函数具有可观察到的副作用:
在初始化过程中,如果初始化表达式是一个prvalue,并且源类型的cv不合格版本与目标类的 类相同,则初始化表达式用于初始化目标对象 :
T x = T(T(T())); // only one call to default constructor of T, to initialize x
IMO你说的是'事物= 5',而不是'事物=东西(5)'。在后者中,一旦定义了一个拷贝构造函数(但是这个拷贝构造函数不能是'explicit'),构造函数'Thing(int)''explicit'就可以了。 – rom1v
Thing thing = Thing(5);
要求(非explicit
)复印件(或移动)-constructor被定义为:
Thing(const Thing &);
(即使它不是所谓优化的原因)。
如何发生的?我没有在任何地方使用“显式” –
@WhiZTiM'explicit'会阻止调用'Thing thing = 5'。 – rom1v
显示“Thing”的整个类定义,或至少全部的构造函数。 –