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

时间:2016-09-18 22:10:12

标签: c++ pointers move-semantics

可能已经提出并已经回答过了,但我不知道该搜索什么。

如果数据成员定义了移动赋值运算符,可以将移动语义用于非指针数据成员吗?

假设我有一个类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;
};

现在显然我可以像这样使用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;
};

但是,如果我希望C<T>::mem_C不是指针而是普通成员,我将如何在移动函数中处理C<T>::mem_C?我当然可以调用移动赋值运算符T::operator=(T&&)将字段mem_C从一个实例移动到另一个实例,但是如何正确重置传递给C的{​​{1}}实例}?

这对我来说至少看错了:

C<T>::C(C&&)

那么,在移动函数中重置非指针数据成员的标准兼容方法是什么?

1 个答案:

答案 0 :(得分:3)

包含类型的移动赋值/构造函数必须将对象保留在&#34;可接受的&#34;无论对于那种类型,这意味着什么。移动类型之外的任何内容都不应该对维护对象的状态负责。

此外,您要确保在父移动构造函数中调用包含类型的移动构造函数,而不是包含类型的移动您在示例中分配

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