Чтобы добавить туда немного.
Традиционное решение, как уже было сказано, объявляет и Copy Constructor
и Assignment Operator
как private
, а не до определяет им.
- Поскольку они
private
, это приведет к ошибке времени компиляции от любого, кто пытается их использовать, но не имеет доступа к закрытым частям класса ...
- Из-за этого у друзей (и самого класса) ошибка будет возникать в виде
undefined symbol
, либо в время соединения (если вы их там найдете), либо, скорее всего, в время выполнения (при попытке загрузить библиотеку).
Конечно, во втором случае это довольно утомительно, потому что вам придется самостоятельно проверять свой код, поскольку у вас нет указания файла и строки, в которой возникает ошибка. К счастью, это ограничено вашими методами класса и друзьями.
Кроме того, стоит отметить, что эти свойства являются транзитивными по пути наследования и компоновки: компилятор будет генерировать только версии по умолчанию Default Constructor
, Copy Constructor
, Assignment Operator
и Destructor
, если он мая.
Это означает, что для любого из этих четырех они автоматически генерируются только , если они доступны для всех баз и атрибутов класса.
// What does boost::noncopyable looks like >
class Uncopyable {
public:
Uncopyable() {}
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};
Вот почему наследование от этого класса (или использование его в качестве атрибута) будет эффективно препятствовать копированию или назначению вашего собственного класса, если вы сами не определите эти операторы.
Обычно наследование выбирается из состава по двум причинам:
- Объект эффективно
Uncopyable
, даже если полиморфизм может быть не таким полезным
- Наследование приводит к
EBO
или Empty Base Optimization
, в то время как атрибут будет адресуемым и, следовательно, будет занимать память (в каждом экземпляре класса), даже если он на самом деле не нужен, у компилятора есть возможность не добавлять это накладные расходы для базового класса.
Вы также можете объявить операторы частными и не определять их в своем собственном классе, но код будет меньше самодокументирующимся , и вы не сможете автоматически искать те классы, которые тогда имейте это свойство (если у вас нет полноценного парсера).
Надеюсь, это пролило некоторый свет на механизм.