【问题标题】:C++: question about move constructor/assignment using Stroustrup exampleC++:关于使用 Stroustrup 示例移动构造函数/赋值的问题
【发布时间】:2020-10-03 14:08:49
【问题描述】:

我了解右值如何调用移动构造函数和移动赋值运算符,但是我很困惑为什么下面 Stroustrup 的移动赋值示例中的相同代码不用于移动构造函数。这是来自 C++ 第 4 版。第 379 页修改了勘误表。

既然类中的所有对象都在移动构造函数中被复制,为什么移动构造函数不能像移动赋值运算符那样简单地交换对象的指针?

也许我遗漏了什么,感谢您的指导!

template<typename T, typename A = allocator<T>>
struct vector_base {                    // memory structure for vector
    A alloc;        // allocator
    T* elem;        // start of allocation
    T* space;       // end of element sequence, start of space allocated for possible expansion
    T* last;        // end of allocated space

    vector_base(const A& a, typename A::size_type n, typename A::size_type m =0)
        : alloc{a}, elem{alloc.allocate(n+m)}, space{elem+n}, last{elem+n+m} { }
    ~vector_base() { alloc.deallocate(elem,last-elem); }

    vector_base(const vector_base&) = delete;           // no copy operations
    vector_base& operator=(const vector_base&) = delete;

    vector_base(vector_base&&);                     // move operations
    vector_base& operator=(vector_base&&);
};
template<typename T, typename A>
vector_base<T,A>::vector_base(vector_base&& a)
    : alloc{a.alloc},
    elem{a.elem},
    space{a.space},
    last{a.last}    
{
    a.elem = a.space = a.last = nullptr;    // no longer owns any memory
}

template<typename T, typename A>
vector_base<T,A>& vector_base<T,A>::operator=(vector_base&& a)
{
    swap(*this,a);
    return *this;
}

【问题讨论】:

  • 在构造函数中,elem 等未初始化。你不想让a拿着随机垃圾。
  • @IgorTandetnik 谢谢,你能详细说明一下吗? elem et al 不是已经在传递给移动构造函数的右值中初始化了吗?那个右值应该是用标准构造函数构造的?
  • a.elem 已初始化。 this-&gt;elem 不是。如果此时进行交换,则 this-&gt;elem 将被初始化,a.elem 将是垃圾。那么a 的析构函数可能会崩溃。
  • @IgorTandetnik 将 a.elem 设为未初始化有什么问题,它的右值是否正确?因此不会再次使用,因为它不是左值?也许我对右值和移动的理解不正确?
  • 它将被销毁。它必须处于其析构函数可以成功运行的状态。

标签: c++ c++11 move-constructor move-assignment-operator


【解决方案1】:

移动构造函数无法进行交换,因为它的成员未初始化,并且析构函数无法在传递的右值上正常工作。因此移动构造函数必须一一复制每个元素并将右值的成员设置为空,这样右值析构函数才能工作。移动赋值可以与右值进行交换,因为当右值析构函数被调用时,数据将是有效的(并且是来自潜在左值的常规构造函数的数据)。

【讨论】:

    猜你喜欢
    • 2021-05-31
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    • 2013-07-21
    • 2016-09-13
    • 2016-05-19
    相关资源
    最近更新 更多