C++ 对象初始化中的复制构造函数
理论上的怀疑。读了一本书,给出了这样一句话:C++ 对象初始化中的复制构造函数,c++,class,copy-constructor,assignment-operator,object-initialization,C++,Class,Copy Constructor,Assignment Operator,Object Initialization,理论上的怀疑。读了一本书,给出了这样一句话:StringBad-metoo=knot其中: StringBad是一个类 结是该类的对象 作者就复制构造函数说了以下几点: 实现可以选择分两种方式处理此语句 步骤:使用复制构造函数创建临时对象并 然后使用赋值将值复制到新对象。即, 初始化总是调用复制构造函数,并使用 =运算符也可以调用赋值运算符 我的实现一步到位: 使用复制构造函数创建metoo对象,如下所示:StringBad metoo(结) 我可以理解,其他实现可以通过以下两个步骤完成
StringBad-metoo=knot代码>其中:
- StringBad是一个类
- 结是该类的对象
作者就复制构造函数说了以下几点:
实现可以选择分两种方式处理此语句
步骤:使用复制构造函数创建临时对象并
然后使用赋值将值复制到新对象。即,
初始化总是调用复制构造函数,并使用
=运算符也可以调用赋值运算符
我的实现一步到位:
- 使用复制构造函数创建metoo对象,如下所示:
StringBad metoo(结)代码>
我可以理解,其他实现可以通过以下两个步骤完成:
- 使用默认构造函数创建一个metoo对象,比如:
StringBad metoo代码>
- 使用重载的asignment操作符将结对象指定给metoo对象
但是作者说初始化总是调用拷贝构造函数。对吗?如果是这样的话,编译器在某些实现中会遵循哪些步骤来分两步实现?我不能用我的原因来测试它,因为我说过它是一步完成的。作者错了。您拥有的是一个带有复制初始化的声明语句,实现这一点的唯一方法是通过StringBad(StringBad const&)
copy构造函数实例化一个新对象。*在这种情况下永远不会调用赋值运算符,甚至不需要存在或可访问
两种变体之间几乎没有区别StringBad-metoo=knot代码>和StringBad metoo(结)代码>
*)或者非常量版本(如果碰巧存在并匹配)。StringBad-metoo()
实际上将metoo
声明为一个不带参数并返回StringBad
的函数,您可能是指StringBad metoo代码>或StringBad metoo{}代码>@Mankarse,谢谢你。更正了。哎呀,这本书不好。引用的文本有太多错误,所以开始没有意义。找一本不同的书。谢谢你。因此,我提出的第二种情况在任何实现中都不会发生。所有人都应该在一个步骤中处理该语句。我在想,使用复制构造函数分两步执行的一种方法是,如果编译器通过交换进行复制,那么它需要使用复制构造函数创建一个类似结的临时对象,然后使用默认的metoo交换它的值当StringBad metoo(结)时,code>语法执行复制初始化代码>语法执行直接初始化。在这种情况下,两者的行为恰好是相同的,因为knot
是StringBad
,但一般来说,它们可以有不同的行为(大约说来,直接初始化可以执行显式转换,而复制初始化只能执行隐式转换)。@Mankarse:是的,确实如此。但是现在,不是吗:-)@KerrekSB:哈哈哈。的确是这样。@Kurospide:在这种情况下,除了复制构造函数,没有别的东西了,这是肯定的。没有神奇的“交换”成员函数或任何东西。最多,编译器可以复制两个副本,复制到StringBad metoo(StringBad(knot))
,但我不确定这是否允许。正如Mankarse所说,一般来说,可能会有一个转换构造函数后跟一个副本构造函数,这在实践中总是会被忽略,但我认为从同一类型的对象初始化不是转换。