Зачем мне делать конструктор копирования и оператор присваивания закрытым и реализованным в C ++? - PullRequest
8 голосов
/ 25 июля 2011

Вдохновленный этим вопросом .

Обычно причина сделать конструктор копирования и оператор присваивания private состоит в том, чтобы сделать класс не копируемым такобъекты могут быть созданы и уничтожены, но не скопированы - в большинстве случаев это происходит потому, что копировать их не имеет смысла.В таких случаях конструктор копирования и оператор присваивания выполняются private и не реализуются - если класс не копируется, то копировать никто не должен.

IsЕсть ли случай, когда конструктор копирования и оператор присваивания должны быть private и иметь значимую реализацию одновременно?

Ответы [ 3 ]

8 голосов
/ 25 июля 2011

Есть два случая, которые сразу приходят на ум:

  1. friend S

    Скажем, что в рамках вашего проекта у вас есть два сильно связанных класса, в которых один должен иметь возможность копировать другой (скажем, как в заводской модели или что-то подобное), но вы не хотите, чтобы весь мир сможет его скопировать.

  2. оберток:

    Допустим, вы хотите иметь возможность условно клонировать некоторый элемент, в зависимости от некоторого внутреннего поведения (например, в зависимости от некоторого состояния с состоянием класса) - самый чистый способ, с точки зрения языка, - это все же разделить копирование на его собственное функция. Это позволило бы хорошо разделить проблемы.

8 голосов
/ 25 июля 2011

Я предполагаю, что это может быть полезно для класса, который содержит свой список - тогда он может копировать экземпляры внутри себя.Это действительно полезно только для класса, который является и элементом, и контейнером:

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

Другая идея - разрешить клонирование в условиях, контролируемых классом.Это может быть полезно, когда копирование может иметь смысл, но только при определенных условиях или разрешениях:

class MyClass
{
private:
    /* Copy ctor and =operator */
public:
    MyClass* clone()
    {
        if (canClone)
        {
            MyClass* cloned = new MyClass(this);
            return cloned;
        }
        else
        {
            return NULL;
        }
    }
};
7 голосов
/ 25 июля 2011
  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;
  }
};

Мы поместили эту оболочку clone(), чтобы позволить пользователю клонировать, однако она также явно отображает, что именно он делает.

...