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

时间:2014-04-10 01:48:13

标签: c++ c++11

我怀疑与继承层次结构中的Move构造函数有关。在C ++ Primer(Stanley Lippman)中,提到继承层次结构中的移动构造函数将如下定义:

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 */}
};

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

 D(D&& d): Base(d) {/*initializers for members of D */}  

但是这最终调用了基类复制构造函数而不是移动构造函数。

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

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

因此,当我们调用std :: 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?
}

我确实理解Base类只会移动与基类相关的成员,并且不会触及派生类成员。但这是一个例外,在std :: move之后,对象的基本部分将处于有效的被破坏状态,并且派生部分仍然处于有意义的状态。请帮我理解这一点。

1 个答案:

答案 0 :(得分:4)

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

class Derived
{
    // data members...
public:
    Derived(Derived&& other) : Base(std::move(other)) { ... }
};

Derived移动构造函数使用otherstd::move强制转换为右值,然后将结果传递给Base移动构造函数,该构造函数涉及{{1}的隐式转换转到Derived&&

Base&&移动构造函数可能会窃取Base的基类成员的内容,但它无法触及派生类成员的内容,因为它只能看到{{1} }}

相关问题