在继承层次结构中移动构造函数

MS *_*nth 3 c++ c++11

我对继承层次结构中的Move构造函数有疑问。在C ++ Primer(Stanley Lippman)中,提到了继承层次结构中的move构造函数将定义如下:

class Base { /* Default Copy control and move constructor */ };

class D : public Base {
public:
  D(const D& d) : Base(d) {/*initializers for members of D */} //This is ok
  D(D&& d): Base(std::move(d)) {/*initializers for members of D */}
};
Run Code Online (Sandbox Code Playgroud)

在move构造函数中,我尝试在调用基本move构造函数时删除std :: move,因为'd'是一个右值引用。

 D(D&& d): Base(d) {/*initializers for members of D */}  
Run Code Online (Sandbox Code Playgroud)

但这最终调用了基类副本构造函数,而不是move构造函数。

为了理解为什么需要std :: move,我在这个论坛上进行了搜索以查看以前的讨论,并且发现了一些答复,这些答复说尽管d是右值引用,但在派生类的move构造函数中它仍然是左值。因此,我们需要在其上调用std :: move,以确保调用了基类move构造函数。我了解这部分。

但是从C ++ Primer中,我了解到一旦调用了std :: move,我们之后就不应再使用该对象。在调用std :: move的表达式结束后,对象将保持有效状态以进行销毁,但其所保存的值可能没有意义。

因此,当我们调用std :: move委托给基类的move构造函数时,当我们回到派生类的move构造函数的主体时,对象将如何保持有意义的状态。

换一种说法:

D(D&& d): Base(std::move(d)) {
  // Would 'd' be in a meaningful state here?
  // After std::move(d), can I still use 'd' here?
}
Run Code Online (Sandbox Code Playgroud)

我确实知道,基类只会移动与基类相关的成员,而派生类成员将不会受到影响。但这是一个例外,在std :: move之后,对象的基础部分将处于有效的可破坏状态,而派生部分仍将处于有意义的状态。请帮助我理解这一点。

Okt*_*ist 5

class Base
{
    // data members...
public:
    Base(Base&& other) = default;
};

class Derived
{
    // data members...
public:
    Derived(Derived&& other) : Base(std::move(other)) { ... }
};
Run Code Online (Sandbox Code Playgroud)

Derived移动构造函数投射other到使用一个rvalue std::move,然后将结果传递给所述Base移动构造函数,它涉及到隐式转换从Derived&&Base&&

Base举措可以在构造窃取的基类成员的胆量other,但不能触及派生类成员的胆量,因为它只看到了Base&&