Подтвердить что ты не робот

Какой самый надежный способ запретить конструктор копирования на С++?

Иногда необходимо запретить конструктор копирования в классе С++, чтобы класс стал "не копируемым". Конечно, operator= должен быть запрещен одновременно.

До сих пор я видел два способа сделать это. Способ 1 - объявить метод private и не дать ему никакой реализации:

class Class {
//useful stuff, then
private:
    Class( const Class& ); //not implemented anywhere
    void operator=( const Class& ); //not implemented anywhere
};

Способ 2 - объявить метод private и дать ему "пустую" реализацию:

class Class {
//useful stuff, then
private:
    Class( const Class& ) {}
    void operator=( const Class& ) {}
};

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

Есть ли серьезные недостатки в первом методе? Какой лучший способ, если он есть и почему?

4b9b3361

Ответ 1

Первый способ - как Boost решает его (исходный код), насколько я знаю, нет никаких недостатков. Фактически, ошибки компоновщика являются большим преимуществом этого метода. Вы хотите, чтобы ошибки находились во время соединения, а не когда ваш клиент выполняет ваш код, и он внезапно падает.

Если вы используете Boost, вы можете сэкономить на некоторых печатных машинах. Это делает то же, что и ваш первый пример:

#include <boost/utility.hpp>

class Class : boost::noncopyable {
// Stuff here
}

Ответ 3

Вы всегда можете наследовать от boost::noncopyable.

В противном случае я никогда не видел причин, по которым номер 2 лучше, чем номер 1, поскольку он позволит вам "скопировать конструкцию" объекта в методы друзей или класса, даже если он фактически не создаст подлинную копию объекта.

Ответ 4

Как другие ответы предлагают что-то еще и на самом деле не пытаются ответить на вопрос, так вот моя попытка:

Итак, какой подход лучше? Это зависит от того, как вы определяете запрет на копирование?

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

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

Обратите внимание, что второй подход не препятствует копированию копий (из-за вызова функций-копий). 1

1. Если вы не будете правильно определять их во втором случае, то копирование не будет работать, как и ожидалось, но это совсем другое. Но дело в том, что второй случай не мешает вызвать функции копирования. Компилятор не генерирует никакого сообщения об ошибке.

Ответ 5

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

Ответ 6

Лично я думаю, что вы ответили на свой собственный вопрос и должны использовать первый подход.

Если вы не хотите, чтобы он был полностью скопирован, как вы сказали, это вызовет ошибку компоновщика. Однако, если вы используете второй подход, и вы в конечном итоге используете конструктор копирования случайно, он будет компилироваться, и он будет запущен; и у вас не будет абсолютно никаких указаний о том, откуда возникла несогласованность, пока вы не распакуете отладчик. Или, как сказал sehe, если вы можете использовать современный компилятор, используйте нотацию С++ 11 '= delete'.