代码之家  ›  专栏  ›  技术社区  ›  Andriy Tylychko

使类不可移动的用例(如果有)是什么?

  •  5
  • Andriy Tylychko  · 技术社区  · 7 年前

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

    // similar to boost::noncopyable
    class noncopyable
    {
    protected:
        constexpr noncopyable() = default;
    
        noncopyable(const noncopyable&) = delete;
        noncopyable& operator=(const noncopyable&) = delete;
    };
    
    class c: private noncopyable
    { /* ... */ };
    

    noncopyable 可能是 noncopyable_and_nonmoveable ).

    现在,让我们从标准库中查找经典的不可复制类,例如。 unique_ptr . 它是不可复制但可移动的,否则其效用将受到限制。我想其他许多情况也是如此。

    这实际上是两个相关的问题:

    1) 为什么 boost::noncopyable 也不可移动吗?这会引起问题,请考虑:

    struct c: private boost::noncopyable
    {
        std::unique_ptr<Something> something;
    
        c(c&&) = default;
        c& operator=(c&&) = default;
    };
    

    不起作用( wandbox )-无法生成移动操作,因为它们不是为基类生成的。您需要手动实现它们->列出您的成员->维护->漏洞。只是默认移动操作 不可复制 将解决问题。

    2) 当可动性有害时,应防止哪些用例?

    3 回复  |  直到 7 年前
        1
  •  8
  •   sehe    7 年前

    如果对象是可移动的,则其地址可以更改:

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

    现在,任何人怎么还提到 a 指向过时的对象或(完全其他的东西)。

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

    scoped_XXXX 通常用于表示不可移动的类型(即保证不可变实例标识的类型)。将其与例如。 unique_XXXX 这意味着一个独特的实例,可以四处移动。 笔记 std::lock_guard<> vs std::unique_lock<> . C++17 amends this 一点

        2
  •  2
  •   WhiZTiM    7 年前

    boost::noncopyable 应该与C++11之前的编译器一起工作。实际上没有什么理由继承 boost::不可复制 使用C++11及更高版本时。如果它在C++11中是可移动的,我们如何建立相同的 移动

    2) 当可动性有害时,应防止哪些用例?

    不可移动性应适用于假定作为外部系统提供给您的各种资源,例如同步原语、表示计算机的ACPI平台等内容的对象,等等。

        3
  •  0
  •   Daniel Trugman    7 年前

    为什么boost::noncopyable也是不可移动的?

    根据C++11标准:

    如果类X的定义没有显式声明移动构造函数,则将隐式声明一个 默认当且仅当

    -X没有用户声明的复制构造函数,

    X没有用户声明的复制赋值运算符,

    X没有用户声明的移动赋值运算符,

    X没有用户声明的析构函数,并且

    所以,我想当你 delete 在复制c'tor和/或复制赋值时,阻止声明默认移动构造函数。

    当可动性有害时,应防止哪些用例?

    我脑海中浮现的第一件事是对象,它们取决于它们在内存空间中的位置,例如 mutex 锿。