Как часто вы реализуете большую тройку?
Я просто размышлял о количестве вопросов здесь, которые касаются "большой тройки" (конструктора копирования, оператора присваивания и деструктора) или о проблемах, вызванных их неправильным выполнением, когда мне пришло в голову, что я могу не помню, в последний раз, когда я сам их реализовал. Быстрый swp в моих двух самых активных проектах показывает, что я реализую все три только в одном классе из примерно 150.
Чтобы не сказать, что я не реализую/не объявляю одно или несколько из них, очевидно, что базовым классам нужен виртуальный деструктор, а большое количество моих классов запрещает копирование с использованием частной копии ctor и присваивания op idiom. Но полностью реализованный, есть этот единственный одинокий класс, который делает некоторый подсчет ссылок.
Итак, мне было интересно, что я необычен в этом? Как часто вы выполняете все три функции? Есть ли какой-либо шаблон для классов, где вы их реализуете?
Ответы
Ответ 1
Я думаю, что вам редко все три. Большинство классов, требующих явного деструктора, не подходят для копирования.
Просто лучше использовать саморазрушающиеся элементы (которые обычно не требуют таких вещей, как копирование), чем большой явный деструктор.
Ответ 2
Как и вы, почти никогда.
Но я не привязан к STL-подходу программирования, где вы копируете все внутри и вокруг в контейнерах - обычно, если это не примитив, я буду использовать указатель, умный или другой.
В основном я использую шаблоны RAII, поэтому избегаю писать деструкторы. Хотя, я поместил пустые тела в мой .cc файл, чтобы помочь сохранить раздувание кода.
И, как и вы, я объявлю их закрытыми и не реализованными, чтобы предотвратить случайное обращение.
Ответ 3
Я редко реализую их, но часто объявляю их частными (создатели копий и присваиваемые операторы, то есть).
Ответ 4
В большинстве случаев, почти никогда. Это связано с тем, что члены, которые используются (на основе ссылок на основе smart ptr и т.д.), Уже реализуют правильную семантику или объект не копируется.
Несколько примеров появляются, когда я нахожу себя в этом:
- разрушающая копия, т.е. перемещение шаблона, такого как auto_ptr или lock
- удалите шаблон, который вряд ли каждый появляется на С++, но я использовал его примерно три раза в своей карьере (и всего неделю назад на самом деле).
- pimpl pattern, где pimpl объявлен в заголовке и управляется интеллектуальным ptr. Затем пустой dtor входит в файл .cc, но по-прежнему классифицируется как "не сгенерированный счётчик"
И еще один тривиальный, который печатает "Я был уничтожен", когда я думаю, что у меня может быть круговая ссылка где-то и просто хочу убедиться.
Ответ 5
Это зависит от того, с какими проблемами вы работаете. Я работаю над новым проектом за последние несколько месяцев, и я думаю, что каждый класс наследуется от boost:: noncopyable. Девять месяцев назад я работал над другим проектом, который использовал POD совсем немного, и я использовал автоматическую копию ctor и оператора присваивания. Если вы используете boost:: shared_ptr (и вы должны быть), редко приходится писать собственный экземпляр ctor или оператор назначения в настоящее время.
Ответ 6
Любой класс, которому принадлежат некоторые члены указателей, должен определить эти три операции для реализации глубокой копии (см. здесь для глубокого описания).