我对继承层次结构中的移动构造函数有疑问。在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 */}
};
在移动构造函数中,由于 'd' 是右值引用,我尝试在调用基类移动构造函数时去掉 std::move。
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?
}
我确实理解基类只会移动与基类相关的成员,而派生类成员不会受到影响。但这是一个例外吗?在使用std::move后,对象的基础部分将处于可以被销毁的有效状态,而派生部分仍将处于有意义的状态。请帮助我理解这个问题。
std::move
和std::forward
都只是转换。它也可以使用移动:https://ideone.com/HCNLST。其中一个只是用于完美转发并提供更多控制。是的,您可以访问未被基类的移动构造函数触及的对象部分。 - Brandon