【问题标题】:Copy constructors in object initialization对象初始化中的复制构造函数
【发布时间】:2012-08-14 15:24:46
【问题描述】:

这里有理论上的疑问。读了一本书,并给出了这样的声明:StringBad metoo = knot; where:

  • StringBad 是一个类
  • knot 是该类的对象

作者对复制构造函数说了以下内容:

实现可以选择以两种方式处理此语句 步骤:使用复制构造函数创建一个临时对象和 然后使用赋值将值复制到新对象。也就是说, 初始化总是调用一个复制构造函数,并使用 = 运算符也可以调用赋值运算符。

我的实现一步完成:

  • 使用复制构造函数创建metoo对象,与此相同:StringBad metoo(knot);

我可以理解,其他实现可以通过这样的两个步骤来完成:

  • 使用默认构造函数创建一个metoo对象,例如:StringBad metoo;
  • 使用重载的赋值运算符将节点对象分配给metoo对象。

但是作者说初始化总是调用复制构造函数。那是对的吗?如果是这样,编译器在某些实现中将遵循哪些步骤以分两步完成?我无法在我的事业中对其进行测试,正如我所说的一步完成。

【问题讨论】:

  • StringBad metoo(); 实际上将metoo 声明为一个不带参数并返回StringBad 的函数,您的意思可能是StringBad metoo; 或StringBad metoo{};。
  • @Mankarse,谢谢。更正了。
  • Ewww,糟糕的书。引用的文字有很多错误,因此开始毫无意义。找一本不同的书。

标签: c++ class copy-constructor assignment-operator object-initialization


【解决方案1】:

作者错了。您所拥有的是带有复制初始化的声明语句,实现这一点的唯一方法是通过 StringBad(StringBad const &) 复制构造函数实例化一个新对象。* 赋值运算符将 never 在此调用情况,甚至不需要存在或可访问。

StringBad metoo = knot; 和StringBad metoo(knot); 这两个变体几乎没有区别。

*) 或非常量版本(如果恰好存在并匹配)。

【讨论】:

  • 谢谢。所以我提出的第二种情况在任何实现中都不会发生。所有人都应该一步处理该声明。我在想,使用复制构造函数分两步执行此操作的一种方法可能是编译器通过交换进行复制,因此它需要使用复制构造函数创建一个临时的类似结的对象,然后将其值与默认值交换metoo。
  • 请注意StringBad metoo = knot; 语法执行copy-initialization,而StringBad metoo(knot); 语法执行direct-initialization。在这种情况下,两者的行为恰好是相同的,因为knot 是StringBad,但总的来说它们可以有不同的行为(大概来说,direct-initialization 可以执行显式转换,而copy-initialization只能进行隐式转换)。
  • @Mankarse:是的,确实。但是现在这个hasbeendiscussedtodeath,不是吗:-)
  • @KerrekSB:哈哈哈。确实有。
  • @Kurospidey:在这种情况下,没有任何但复制构造函数,这是有保证的。没有神奇的“交换”成员函数或任何东西。充其量,编译器可以制作 两个 副本,类似于StringBad metoo(StringBad(knot)),但我实际上不确定这是否允许。正如 Mankarse 所说,general 可能有一个 conversion 构造函数,后跟一个复制构造函数,实际上总是会省略,但我认为从相同的对象初始化类型不是转换。
猜你喜欢
  • 1970-01-01
  • 2012-03-05
  • 2021-11-06
  • 1970-01-01
  • 1970-01-01
  • 2021-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多