Правило трех в C++

Я читал, что правило трех, что такое правило трех? резюмируется следующим образом:

Если вам нужно явно объявить деструктор, конструктор копирования или оператор копирования, вам, вероятно, нужно явно объявить все три из них.

Мой вопрос: в приложении C++ у меня есть класс, который управляет ресурсами (есть деструктор, который обрабатывает удаление указателей). Я знаю, что приложение повсеместно использует оператор присваивания, но я абсолютно уверен, что в приложении нет конструктора копирования, т.е. использование типа Class c(..); Class d(c); поэтому при этих обстоятельствах мне все еще необходимо реализовать как оператор присваивания, так и конструктор копирования? Или одного оператора присваивания будет достаточно? Возможно ли, чтобы оператор присваивания как-то использовал конструктор копирования?

Цените ваши мысли.

3 ответа

Решение

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

class C
{
private:
    C(const C&); // not implemented
};

(в C++11 вы можете использовать новый = delete синтаксис). Тем не менее, вы должны делать это, только если вы абсолютно уверены, что это никогда не понадобится. В противном случае, вам может быть лучше его реализовать. Важно не оставлять все как есть, так как в этом случае компилятор предоставит конструктор копирования для каждого элемента по умолчанию, который будет делать не то, что нужно - это проблема, ожидающая своего появления.

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

Я абсолютно уверен, что нет применения в приложении конструктора копирования, то есть, использование типа Class c(..); Класс d(c)

Знаете ли вы, что следующий код

Foo c;
Foo b = c;

вызывает конструктор копирования, а НЕ оператор присваивания? Я бы реализовал конструктор копирования просто для безопасности.

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

Если с точки зрения дизайна ваш класс имеет смысл быть некопируемым, вы можете объявить, но не определить копию ctor/assignment op.

Другие вопросы по тегам