为什么我要将复制构造函数和赋值运算符设为私有并在C++中实现?

sha*_*oth 8 c++ copy-constructor assignment-operator

灵感来自这个问题.

通常,创建复制构造函数和赋值运算符的原因private使类不可复制,以便只能创建和销毁对象,但不能复制 - 大多数情况下,因为复制它们没有任何意义.在这种情况下,复制构造函数和赋值运算符都已生成private 且未实现 - 如果类不可复制,则无人应复制.

复制构造函数和赋值运算符是否需要private同时具有有意义的实现?

Eli*_*ser 8

我的猜测是,这对于持有自己列表的类很有用 - 然后它可以在内部复制实例.这实际上只对作为项和容器的类有用:

class MyItems
{
private:
    /* Copy ctor and =operator */
    List list;
public:
    void AddItems(MyItems* items)
    {
        MyItems* added = new MyItems(items);
        list.Add(added);
    }
};
Run Code Online (Sandbox Code Playgroud)

另一个想法是允许在班级控制的情况下进行克隆.当复制有意义时,这可能很有用,但仅限于特定条件或权限:

class MyClass
{
private:
    /* Copy ctor and =operator */
public:
    MyClass* clone()
    {
        if (canClone)
        {
            MyClass* cloned = new MyClass(this);
            return cloned;
        }
        else
        {
            return NULL;
        }
    }
};
Run Code Online (Sandbox Code Playgroud)


Nat*_*ate 8

有两种情况立即浮现在脑海中:

  1. friendS:

    比方说,作为你设计的一部分,你有两个高度耦合的类,其中一个需要能够复制另一个(比如,在工厂模型或其他类似),但你不想让整个世界成为能够复制它.

  2. 包装:

    假设您希望能够有条件地克隆某些元素,具体取决于某些内部行为(例如,取决于某些类状态条件) - 从语言角度来看,最简洁的方法仍然是将复制分离为自己的函数.这样可以很好地分离关注点.


iam*_*ind 7

  1. 我们制作复制构造函数并且operator =未实现,以便即使是一个friend也无法访问它.如果您实施,则意味着您希望friend获得访问权限.这是一个设计决定.
  2. 你想做明确的克隆 ; 即允许复制,但也使其代码"脏"看起来(类似于C++样式的转换操作,在代码中显示污垢)

例如

class A {
  A(const A& obj) { ... }
  A& operator = (const A& obj) { ... }
public:
  A& clone(const A& obj)
  {
    *this = obj;
    return *this;
  }
};
Run Code Online (Sandbox Code Playgroud)

我们已经将这个包装器clone()允许用户进行克隆,但是它也明确地显示了他/她正在做什么.