Копирование конструкторов традиционно вездесущим в программах на C++. Тем не менее, я сомневаюсь, есть ли веские основания для этого с C++ 11.Можем ли мы попрощаться с копиями конструкторов?
Даже когда логике программы не нужно копировать объекты, копии Конструкторов (уса. Умолчанию) часто включаются с единственной целью объекта перераспределения. Без конструктора копирования вы не могли хранить объекты в std::vector
или даже возвращать объект из функции.
Однако, поскольку C++ 11, перемещение конструкторов было связано с перераспределением объекта.
Другим вариантом использования для копировщиков было просто создание клонов объектов. Тем не менее, я вполне убежден, что .copy()
или .clone()
метод лучше всего подходит для этой роли, чем конструктор копирования, потому что ... объекты
Копирование не очень обычным явлением. Конечно, иногда необходимо, чтобы интерфейс объекта содержал метод «сделать дубликат себя», но только иногда. И когда это так, явное лучше, чем неявное.
Иногда объект может выставлять несколько разных методов
.copy()
, потому что в разных контекстах копия может потребоваться создать по-другому (например, более мелкие или глубокие).В некоторых контекстах мы бы хотели, чтобы методы
.copy()
выполняли нетривиальные вещи, связанные с логикой программы (приращение некоторого счетчика или, возможно, создание нового уникального имени для копии). Я бы не принял код, который имеет неочевидную логику в конструкторе копирования.Последнее, что не менее важно, метод
.copy()
может быть виртуальным, если это необходимо, что позволяет решить проблему slicing.
Единственные случаи, когда я на самом деле хочу использовать конструктор копирования являются:
- RAII ручки воспроизводимую ресурсов (вполне очевидно)
- Структуры, которые предназначены, чтобы быть используются как встроенные типы, такие как математические векторы или матрицы -
просто потому, что они скопированы часто иvec3 b = a.copy()
слишком многословно.
Side Примечание: Я рассмотрел тот факт, что конструктор копирование необходим для CAS, но CAS необходим для
operator=(const T&)
который я считаю избыточное базирование на то же рассуждение;
.copy()
+operator=(T&&) = default
было бы предпочтительнее, если вам действительно нужно.)
Для меня этого вполне достаточно стимула использовать T(const T&) = delete
везде по умолчанию и обеспечить способ .copy()
при необходимости. (Возможно, также private T(const T&) = default
, чтобы иметь возможность писать copy()
или virtual copy()
без шаблона.)
В: Являются ли приведенные выше аргументы правильными или у меня отсутствуют какие-либо веские причины, по которым на самом деле нужны логические объекты или каким-то образом выигрывают от конструкторов копирования?
В частности, я прав в том, что конструкторы перехватили ответственность за перераспределение объектов на C++ 11 полностью? Я использую «перераспределение» неофициально для всех ситуаций, когда объект нужно перемещать где-то еще в памяти, не изменяя его состояние.
«Копирование объектов на самом деле не является обычным явлением». - Я бы сказал, что это довольно распространено, учитывая, что C++ по умолчанию использует семантику значений. Два объекта с одинаковым значением должны представлять одно и то же. –
Отключение копирования по умолчанию может иметь некоторые достоинства; но почему бы вам включить его через функцию-член, а не идиоматическое использование конструкторов копирования? –
@sftrabbit: необязательно: значения не являются полиморфными, ссылки и указатели. Если вы хотите, чтобы полиморфизм во время выполнения на C++ идентифицировал объекты по их адресам, а не значения (которые представляют собой только «состояние», а не «идентификатор»). Два 'Person'-s, имеющие одно и то же' m_name', не совпадают с 'Person'. –