Отключить оператор копирования-присваивания, сгенерированный компилятором
Когда я пишу класс (скажем class nocopy
), можно ли полностью исключить существование оператора копирования? Если я его не определяю, а кто-то другой пишет что-то вроде
nocopy A;
nocopy B;
A = B;
компилятор автоматически сгенерирует определение. Если я сам определяю его, я предохраню компилятор от автоматического генерации, но указанный выше код будет по-прежнему легальным.
Я хочу, чтобы приведенный выше код был незаконным и генерировал ошибку времени компиляции. Как это сделать?
Ответы
Ответ 1
Вы просто объявляете конструктор копирования с private
спецификатором доступа и даже не определяете его.
Любой, кто пытается его использовать, получит ошибку компиляции, так как объявлен private
.
Если кто-то использует его даже косвенно, вы получите сообщение об ошибке.
Вы не можете сделать ничего больше, чем в С++ 03.
Однако в С++ 11 вы можете Явно удалить специальные функции-члены.
Например:
struct NonCopyable {
NonCopyable & operator=(const NonCopyable&) = delete;
NonCopyable(const NonCopyable&) = delete;
NonCopyable() = default;
};
Ответ 2
Обычный способ - объявить конструктор копирования и оператор присваивания частным, что вызывает ошибки компиляции, как объяснил Алс.
Вывод из boost::noncopyable
выполнит эту работу для вас.
Ответ 3
Если вы наследуете от boost::noncopyable
, вы получите ошибку времени компиляции при попытке создания конструктора копирования. Я обнаружил, что использование этих сообщений об ошибках (с MSVC) бесполезно, поскольку они обычно не указывают на строку, вызвавшую ошибку. Альтернативой является объявление конструктора-копии private
и оставить его undefined или определить его с помощью BOOST_STATIC_ASSERT(false)
. Если вы работаете с С++ 11, вы также можете delete
создать свой конструктор копирования:
class nocopy
{
nocopy( nocopy const& ) = delete;
};