c++ - 使类不可 move 的用例(如果有)是什么?

标签 c++ boost move

考虑一种使类不可复制的经典方法:

// similar to boost::noncopyable
class noncopyable
{
protected:
    constexpr noncopyable() = default;

    noncopyable(const noncopyable&) = delete;
    noncopyable& operator=(const noncopyable&) = delete;
};

class c: private noncopyable
{ /* ... */ };

由于声明任何复制操作会阻止自动生成 move 操作,这会自动使所有派生类(默认情况下)也不可 move (因此 noncopyable 的全名将是 noncopyable_and_nonmoveable).

现在让我们从标准库中寻找经典的不可复制类,例如唯一指针。它不可复制但可 move ,否则它的实用性将受到限制。我想对于许多其他情况也是如此。

实际上我想不出任何一个类应该是不可 move 的例子。我的论点是:即使没有计划 move 一个类,也有可能会因可能造成伤害的错误而导致 move 。

其实是两个相关的问题:

1) 为什么 boost::noncopyable 也是不可 move 的?这会导致问题,请考虑:

struct c: private boost::noncopyable
{
    std::unique_ptr<Something> something;

    c(c&&) = default;
    c& operator=(c&&) = default;
};

不起作用 ( wandbox ) - 无法生成 move 操作,因为它们不是为基类生成的。您需要手动实现它们 -> 列出您的成员 -> 维护 -> 错误。只需在 noncopyable 中默认 move 操作即可解决问题。

2) 可 move 性有害且应该避免的用例有哪些?

最佳答案

不可 move 使您可以更好地控制对象标识。

如果一个对象是可 move 的,它的地址就可以改变:

moveonly a;
b = std::move(a);

现在,任何人仍然可以引用 a指向陈旧的对象或(完全不同的东西)。

出现这种情况的其他情况是当您有依赖于对象标识(“地址稳定性”)的外部逻辑时,如果您愿意的话,例如使用 pthread 互斥锁:Move constructor for std::mutex

附录 - 命名约定 scoped_XXXX通常用于暗示不可 move 的类型(即保证不可变实例标识的类型)。将此与例如unique_XXXX这意味着一个独特的实例,可以四处 move 。 注意 然而,标准库并未完全采用此命名约定:示例:std::lock_guard<>对比std::unique_lock<> . C++17 amends this一点

关于c++ - 使类不可 move 的用例(如果有)是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46666078/

相关文章:

Python - 一次 move 10 个文件

html - 滚动文本 - 条目同时显示

c++ - 何时创建和销毁静态成员?

c++ - 递归文件夹读取C++

c++ - 从基类构造函数调用派生类的虚函数?

c++ - 用 boost::spirit 解析成一个 vector<vector<double>>

c++ - BGL 添加具有多个属性的边

c++ - std::make_pair、std::unordered_map 和从键类型 move 构造函数的用法

c++ - 优化场景图

c++ - 从 cin 获取 C++ 结构中多个枚举的输入