Все ресурсы, захваченные классом, должны быть освобождены деструктором класса
Причина
Предотвращение утечек ресурсов, особенно в случае ошибок.
Примечание
Для ресурсов, представленных классами с полным набором операций по умолчанию, это происходит автоматически.
Пример
class X {
ifstream f; // может владеть файлом
// ... нет определённых или =deleted операций по умолчанию ...
};
ifstream объекта X неявно закрывает любой открытый файл при уничтожении X.
Пример (плохой)
class X2 { // плохо
FILE* f; // может владеть файлом
// ... нет определённых или =deleted операций по умолчанию ...
};
X2 может допустить утечку файлового дескриптора.
Примечание
А как насчёт сокета, который не закрывается? Деструктор, close или операция очистки никогда не должны завершаться с ошибкой. Если это всё же происходит, у нас есть проблема, для которой нет хорошего решения. Для начала: автор деструктора не знает, почему вызывается деструктор, и не может «отказаться действовать», выбросив исключение. См. обсуждение. Хуже того, многие операции «закрытия/освобождения» не допускают повторных попыток. Многие пытались решить эту проблему, но общее решение неизвестно. По возможности рассматривайте неудачу при закрытии/очистке как фундаментальную ошибку дизайна и завершайте программу.
Примечание
Класс может содержать указатели и ссылки на объекты, которыми он не владеет. Очевидно, такие объекты не должны быть delete-нуты деструктором класса. Например:
Preprocessor pp { /* ... */ };
Parser p { pp, /* ... */ };
Type_checker tc { p, /* ... */ };
Здесь p ссылается на pp, но не владеет им.
Контроль
(например, объявленные как gsl::owner), они должны упоминаться в его деструкторе.
(например, смотреть в конструкторы).
- (Простой) Если класс имеет указатели или ссылочные члены, являющиеся владельцами
- (Сложный) Определить, являются ли члены-указатели или ссылки владельцами, когда нет явного указания на владение