在继承层次结构中移动构造函数 [英] Move constructors in inheritance hierarchy

查看:38
本文介绍了在继承层次结构中移动构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a doubt related to Move constructors in Inheritance hierarchy. In C++ Primer (Stanley Lippman) it is mentioned that the move constructor in an inheritance hierarchy would be defined like this:

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'是一个右值引用.

In the move constructor, I tried removing std::move while calling the base move constructor since 'd' is a rvalue reference.

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

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

But this ended up calling the base class copy constructor instead of the move constructor.

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

To understand why std::move is required, I searched this forum to see previous discussions and I found out a few replies which said that though 'd' is a rvalue reference, within the derived class's move constructor it is still a lvalue. Hence we need to call std::move on it to ensure that base class move constructor is called. I understood this part.

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

But from C++ Primer, I understand that once std::move is called we should not use the object at all after that. After the expression in which std::move is called ends, the object will remain in a valid state for destruction but the values it holds may not be meaningful.

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

So when we call std::move to delegate to the base class's move constructor how then would the object remain in a meaningful state when we come back to the body of the derived class's move constructor.

换句话说:

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之后,对象的基础部分将处于有效的被破坏状态,而派生部分仍将处于有意义的状态.请帮助我理解这一点.

I do understand that the Base class would just move the members related to the base class alone and that the derived class members won't be touched. But is this an exception where after std::move the base part of the object would be in a valid to be destructed state and the derived part would still be in a meaningful state. Please help me understand this.

推荐答案

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

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

Derived 的move构造函数使用 std :: move other 强制转换为右值,然后将结果传递给 Base 移动构造函数,它涉及从 Derived&& Base&& 的隐式转换.

The Derived move constructor casts other to an rvalue using std::move, then passes the result to the Base move constructor, which involves an implicit cast from Derived&& to Base&&.

Base 的move构造函数可能会窃取 other 的基类成员的胆量,但是它不能触及派生类成员的胆量,因为它只能看到一个 Base&& .

The Base move constructor might steal the guts of the base class members of other, but it can't touch the guts of the derived class members because it only sees a Base&&.

这篇关于在继承层次结构中移动构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆