C++ C++;构造函数调用的样式
我有一个名为C++ C++;构造函数调用的样式,c++,constructor,initialization,language-lawyer,C++,Constructor,Initialization,Language Lawyer,我有一个名为Thing的对象,它的构造函数取int 此代码按预期工作: Thing(5) 然而,我无意中写了以下内容: Thing=Thing(5);//注意:没有“新的” 并得到错误没有匹配的构造函数来初始化“Thing”。后一种代码的实际含义是什么?我知道如果我在那里抛出一个new,这意味着什么,但如果没有new,这意味着什么 Thing thing = Thing(5); 需要定义(非显式)副本(或移动)-构造函数: Thing(const Thing &); (即使不是出于优
Thing
的对象,它的构造函数取int
此代码按预期工作:
Thing(5)代码>
然而,我无意中写了以下内容:
Thing=Thing(5);//注意:没有“新的”
并得到错误没有匹配的构造函数来初始化“Thing”
。后一种代码的实际含义是什么?我知道如果我在那里抛出一个new
,这意味着什么,但如果没有new,这意味着什么
Thing thing = Thing(5);
需要定义(非
显式)副本(或移动)-构造函数:
Thing(const Thing &);
(即使不是出于优化原因而调用它)。Thing(5)
是,thing
是由相应的构造函数(即thing::thing(int)
)直接构造的
Thing-Thing=Thing(5)代码>是,这与直接初始化不完全相同。但在这种情况下,由于C++17,它也将直接调用Thing::Thing(int)
来构造对象,因此它与这里的直接初始化具有相同的效果
首先,如果T
是一个类类型,并且初始值设定项是一个prvalue表达式,其cv非限定类型与T
是同一个类,则初始值设定项表达式本身(而不是它的临时物化)用于初始化目标对象:请参阅
在C++17之前,第二种情况(即复制初始化)要求复制/移动构造函数可访问且非显式;如果是这种情况,并且您使用的编译器不支持C++17,则会导致错误
如果T
是类类型,而other
类型的cv非限定版本是T
或派生自T
的类,则检查T
的非显式构造函数,并通过重载解析选择最佳匹配。然后调用构造函数来初始化对象
请注意,在C++17中,代码可以很好地编译。根据的规则,在这种情况下,复制/移动构造函数不需要是可访问的和显式的
在下列情况下,编译器必须省略
类对象的复制和移动构造函数,即使复制/移动
构造函数和析构函数有明显的副作用:
- 在初始化中,如果初始值设定项表达式是prvalue,并且源类型的cv非限定版本与
类,初始值设定项表达式用于
初始化目标对象:
T x = T(T(T())); // only one call to default constructor of T, to initialize x
这是怎么发生的?我自己没有使用显式anywhere@WhiZTiMexplicit
将阻止调用Thing Thing=5
。显示Thing
的整个类定义,或者至少显示它的所有构造函数。我明白了,所以公式是生成一个Thing
,然后复制它(毫无意义)。如果不查看类构造函数,则无法得出结论/members@P0W,自事(5)代码>工作时,至少有一个构造函数Thing(int)
(explicit
或not)。如果Thing=Thing(5)
不起作用,我们可以断定缺少一个副本(/move)-构造函数。你能提供一个反例吗?@БСааББааааа是。@P0W如果Thing Thing(5)
起作用而Thing Thing=Thing(5)
不起作用,则缺少一个非显式的复制(或移动)构造函数。您提供的示例使这两个声明都可以工作,而无需显式定义复制(或移动)构造函数。这并不矛盾;-)一个反例是一个工作的东西(5)
,一个非工作的东西=东西(5)
,它的解决方案可以使它工作,而无需定义一个复制(或移动)构造函数。在后者中,只要定义了一个复制构造函数,就可以使构造函数Thing(int)
显式
(但是这个复制构造函数不能是显式
)。