不可复制和不可移动?

时间:2016-03-02 09:48:02

标签: c++ c++11

我想创建一个noncopyable和nonmovable的基类。

class noncopyable {
protected:
  noncopyable() = default;
  ~noncopyable() = default;

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

class nonmovable {
protected:
  nonmovable() = default;
  ~nonmovable() = default;

  nonmovable(nonmovable &&) = delete;
  nonmovable &operator=(nonmovable &&) = delete;
};

是否存在类应该是不可复制和不可移动的情况?

class non : public noncopyable, public nonmovable {
};

class foo : public non {
};

如果有,那么" non"的方便名称应该是什么?这里上课?

3 个答案:

答案 0 :(得分:4)

有人认为,例如herenonmoveable首先证明是一个坏主意。

有四种合理的选择:

  1. 类型是自然可复制和可移动的。
  2. 类型不可复制,但可移动 如果它正在管理资源,则经常发生这种情况,并且复制资源是不可能的,或者是非常昂贵的以至于不希望的。
  3. 类型没有特殊的可移动性 - 移动ctor只需调用copy ctor 如果出于技术原因,您不希望为此类型的对象创建“空状态”,或者没有便宜/自然的方式将移动的对象保留在任何可接受的状态,则会发生这种情况。
  4. 类型既不可复制也不可移动 这可能发生在静态单例或类似的情况下,移动或复制它是程序中永远不会发生的事情,并且您希望防止发生编译时错误。
  5. 如果类型是可复制的,但移动它失败,这绝对是一个糟糕的安排,而应该移动后备复制。

    表示,当副本没问题时,移动失败没有任何优势,它只会抑制泛型编程。

    所以也许你应该只有“noncopyable”和“non”,但不是“nonmoveable”?

答案 1 :(得分:3)

While a "noncopyable" will work, an "nonmovable" base class will not provide what you expect:

#include <utility>
#include <iostream>

struct nonmovable
{
    nonmovable() = default;
    nonmovable(const nonmovable&) { std::cout << "copy\n"; }
    nonmovable& operator = (const nonmovable&) { std::cout << "asign\n"; return *this; }
    nonmovable(nonmovable&&) = delete;
    nonmovable& operator = (nonmovable&&)  = delete;
};

struct X : nonmovable {};

int main()
{
    nonmovable n0;
    nonmovable n1(n0);
    // error: use of deleted function ‘nonmovable::nonmovable(nonmovable&&)’:
    //nonmovable n2(std::move(n0));

    X x0;
    X x1(x0);
    // However, X has a copy constructor not applying a move.
    X x2(std::move(x0));
}

In addition, move construction and move assignment must be enabled explicitly after deletion of the copy constructor, if desiered:

struct noncopyable
{
    noncopyable() = default;
    // Deletion of copy constructor and copy assignment makes the class
    // non-movable, too.
    noncopyable(const noncopyable&) = delete;
    noncopyable& operator = (const noncopyable&) = delete;

    // Move construction and move assignment must be enabled explicitly, if desiered.
    noncopyable(noncopyable&&) = default;
    noncopyable& operator = (noncopyable&&)  = default;
};

The, names "noncopyable" and "nonmovable" itself are good descriptive names. However, "boost::noncopyable" is both (non copyable and non movable), which might be a better (historical) design decision.

答案 2 :(得分:-3)

as an example - signleton pattern. Also, if u defined copy-constructor/assignment operator/destructor, move-constructor/assignment wont be generated.