简体   繁体   English

使用非指针数据成员移动语义

[英]Move semantics with non-pointer data members

Probably this has been asked and answered already, but I don't know what to search for. 可能已经有人问过并回答了,但是我不知道要搜索什么。

Can move semantics be used for non-pointer data members, if the data members have move assignment operators defined? 如果数据成员定义了移动分配运算符,可以将移动语义用于非指针数据成员吗?

Suppose I have a class M that defines M::operator=(M&&) like this: 假设我有一个M类,它定义了M::operator=(M&&)如下所示:

template <class T>
class M
{
public: 
    M()
    {
        mem_M = new T;
    }

    M& operator=(M&& src)
    {
        if (this != &src)
        {
            mem_M = src.mem_M;
            src.mem_M = nullptr;
        }
        return *this;
    }

private:    
    T* mem_M;
};

Now obviously I can have a class C<T> like this, with a move constructor that makes no use of T 's move assignment operator: 现在显然我可以拥有一个这样的类C<T> ,其移动构造函数不使用T的移动赋值运算符:

template <class T>
class C
{
public:
    C ()
    {
        mem_C = new T;
    }
    C (C&& rhs)
    {
        mem_C = rhs.mem_C;
        rhs.mem_C = nullptr;
    }

private:
    T* mem_C;
};

However, what if I wanted C<T>::mem_C to not be a pointer but an ordinary member, how would I deal with C<T>::mem_C in the move-functions? 但是,如果我希望C<T>::mem_C不是指针而是普通成员,该如何在移动功能中处理C<T>::mem_C I can of course invoke the move assignment operator T::operator=(T&&) to move the filed mem_C from one instance to the other, but how do I properly reset the instance of C passed to C<T>::C(C&&) ? 当然,我可以调用移动赋值操作符T::operator=(T&&)到日提交的移动mem_C从一个实例向另一,但我如何正确复位的实例C传递给C<T>::C(C&&)

This at least looks wrong to me: 这至少对我来说似乎是错误的:

template <class T>
class C
{
public:
    C ()
    {
        mem_C = T();
    }
    C (C<T>&& rhs)
    {
        mem_C = std::move(rhs.mem_C);
        rhs.mem_C = T();          // ?? like this?
    }

private:
    T mem_C;
};

So, what is the standard compliant way to reset non-pointer data members in move functions? 那么,在移动功能中重置非指针数据成员的标准兼容方法是什么?

The move assignment/constructors for the contained types must leave the objects in an "acceptable" state, whatever that means for that type. 所包含类型的移动分配/构造方法必须使对象处于“可接受”状态,无论该类型意味着什么。 Nothing outside the type being moved should have any responsibility for maintaining the state of the object. 要移动的类型之外的任何东西都不对维护对象的状态负责。

Also, you want to make sure you're calling move constructors of contained types in your parent move constructor , not the contained type's move assignment as you are in your example: 另外,您想确保在父级move 构造 函数中调用包含类型的move 构造函数 ,而不是在示例中调用包含类型的move 赋值

// move constructor calls move constructor of contained elements
C (C<T>&& rhs) : mem_c(std::move(rhs.mem_c))
{
    // anything in here is using already-constructed data members
}

// move assignment calls move assignment of contained elements
C & operator=(C<T>&& rhs) {
    mem_c = std::move(rhs.mem_c);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM