在继承层次结构中移动构造函数
Move constructors in inheritance hierarchy
我对继承层次结构中的Move构造函数有疑问。在C++初级读本(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 */}
};
在move构造函数中,我在调用基move构造函数时尝试删除std::move,因为"d"是一个右值引用。
D(D&& d): Base(d) {/*initializers for members of D */}
但这最终调用了基类复制构造函数,而不是移动构造函数。
为了理解为什么需要std::move,我在这个论坛上搜索了以前的讨论,发现了一些回复,其中说虽然"d"是一个右值引用,但在派生类的move构造函数中,它仍然是一个左值。因此,我们需要调用std::move来确保基类move构造函数被调用。我理解这部分。
但从C++初级读本中,我了解到一旦调用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?
}
我知道基类只会单独移动与基类相关的成员,派生类成员不会被触及。但这是一个例外吗?在std::move之后,对象的基础部分将处于有效的待销毁状态,而派生部分仍处于有意义的状态。请帮我理解这一点。
class Base
{
// data members...
public:
Base(Base&& other) = default;
};
class Derived
{
// data members...
public:
Derived(Derived&& other) : Base(std::move(other)) { ... }
};
Derived
移动构造函数使用std::move
将other
强制转换为右值,然后将结果传递给Base
移动构造函数,这涉及到从Derived&&
到Base&&
的隐式强制转换。
Base
移动构造函数可能会窃取other
基类成员的内脏,但它不能触及派生类成员的内脏因为它只看到一个Base&&
。
相关文章:
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 为什么调用复制构造函数而不是移动构造函数?
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 移动构造函数和右值引用
- 为什么 std::memmove 中联合的默认非平凡移动构造函数C++?
- 具有专用化的模板类中的可靠条件复制和移动构造函数
- C++:为什么不调用移动构造函数?
- 移动构造函数永远不会被调用
- C++:关于使用 Stroustrup 示例移动构造函数/赋值的问题
- 运算符+ 的规范实现涉及额外的移动构造函数
- C ++为什么在移动构造函数中需要移动/前进
- 为什么在删除"移动构造函数"时使用"复制构造函数"?
- 为什么这里不调用移动构造函数?
- 隐式移动构造函数
- 如何为具有私有成员的派生类实现移动构造函数
- 为什么不调用移动构造函数
- 是否可以避免在以下代码中复制/移动构造函数的需要?