【问题标题】:Move constructor C++11移动构造函数 C++11
【发布时间】:2018-01-23 08:50:18
【问题描述】:

我正在查看一些我继承的代码,它有一个矩阵类,它在 C++ 中实现二维矩阵,并具有移动构造函数和赋值运算符。

它的实现方式如下:

template<typename T, int rows, int cols>
class matrix_data {
    ...
    std::unique_ptr<T[]> data_;
    // Some definitions
    typedef matrix_data<T, rows, cols> this_type

    matrix_data(this_type && other)
    {
        std::swap(data_, other.data_);
    }
};

现在,我不确定为什么要在此处交换数据指针。我认为它应该类似于

data_ = std::move(other.data_);

我猜测交换仍然可以,因为other 实例在移动后无论如何都应该处于无效状态。

我的问题是我是否可以将语句替换为data_ = std::move(other.data_); 是否有一些unique_ptr 删除内容是进行交换而不是移动的原因,即如果我进行移动,原始数据是否会被正确删除?

【问题讨论】:

  • 用已知的临时(即将过期)交换对象内容可确保清除对象的当前数据成员。在这种情况下,它可能不是必需的,但这是此操作的常见模式。
  • 如果您在对象中添加或删除数据成员,则可以减少一项更改功能。析构函数将(可能)必须更改,但移动构造函数不会,这使得代码更改不易出错。此外,std::swap 通常可以提供强异常保证,然后可以将其传播到移动构造函数。
  • 我认为“另一个”必须保持在有效(但未指定)状态,否则它的破坏将被破坏。
  • 最佳解决方案,matrix_data(this_type &amp;&amp; other) = default;。使用std::swap 没有意义,它的工作量更大。
  • 如果类的... 部分包含一些其他构造函数,这很有可能,您必须专门要求一个移动构造函数(但可以使用@ 987654329@版本)。

标签: c++ c++11 move move-semantics unique-ptr


【解决方案1】:

回答你的问题:

是的,您可以将交换替换为

data_ = std::move(other.data_);

但正如 cmets 所建议的那样,当您不实现移动构造函数时,只要您既不实现复制构造函数、复制赋值运算符、移动赋值运算符或析构函数,就会发生这种情况。如果您已经实现了上述其中一项,将移动构造函数标记为=default 也可以完成这项工作。

在这种情况下确实不需要交换对象的内容,因为实际上没有什么可以交换的,因为这是一个(移动)构造函数,this-&gt;data_ 不指向任何先前分配的内存位置,应该在指向它的指针已被覆盖。

因此交换通常在实现移动赋值 操作符时完成,因为在这种情况下this-&gt;data_ 通常持有一个指向需要释放的内存位置的指针有时。通过将此指针放入被移动对象中,当被移动对象的析构函数被调用时,它指向的内存将被释放。

【讨论】:

    猜你喜欢
    • 2012-05-11
    • 1970-01-01
    • 2014-02-22
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多