移动构造是否未指定专门类的属性?

问题描述 投票:0回答:1

考虑类

Dog
继承自
Animal
:

class Animal { … };

class Dog: public Animal {
 public:
  Dog(Dog&& other)
    : Animal(std::move(other)),
      breed(std::move(other.breed)) {
  }

 private:
  std::string breed;
};

移动构造函数首先使用

std::move(other)
构造父对象。 然而,标准库说

[移动操作后,]移出的对象应置于有效但未指定的状态。

如果我理解正确的话,这意味着

other
指向的对象现在处于未指定状态。这意味着构造属性
breed
的下一行将导致未指定的值。

这是正确的吗?

c++ inheritance move-semantics
1个回答
0
投票

Animal(std::move(other))
之后,基类处于由
Animal
作者通过他/她设计的
Animal
移动构造函数控制的状态。
Animal
的客户不应假设任何特定状态,除非
Animal
的作者已经记录了此类状态。

理论上,

Animal
的作者可以设计
Animal
移动构造函数来假设它是
Dog
的子对象,并进入
Dog
并摆弄数据成员
breed
。 这样做是非常不正统的。
Animal
的良好设计通常不会假设诸如从中派生出哪些类之类的事情。

一般来说,假设代码行为良好,基类

Animal
不知道它是由
Dog
派生的,并且其移动构造函数不会更改派生类的数据成员。 当然,如果
Animal
的移动构造函数是由编译器提供的,则它不会执行此操作。 编译器提供的移动构造函数仅移动其自己的基址和成员(按该顺序和声明顺序)。

您为

Dog
显示的移动构造函数是普遍接受的正确移动构造函数,并且与编译器提供的移动构造函数相同,即由
Dog(Dog&&) = default;
生成的移动构造函数。

© www.soinside.com 2019 - 2024. All rights reserved.