Удаленный деструктор

165
16 мая 2019, 02:50

Читаю "A Tour of C++" Страуструпа, и наталкиваюсь на стр. 77 на такой совет:

If a class has a pointer member, it probably needs a user-defined or deleted destructor, copy and move.

Т.е. вроде бы как

Если класс имеет член-указатель, вероятно, ему требуются пользовательские или удаленные деструктор, копирование и перемещение.

Про копирование и перемещение - нет вопросов, все понятно, про пользовательский деструктор - тоже.

Но что может означать удаленный деструктор? Не в плане написать

~Class() = delete;

а что это может дать? Ведь такой объект нельзя будет удалить ни автоматом по выходу из области видимости, ни через delete (понятно, локальный и выделенный через new соответственно).

В чем тут глубокий смысл - создавать бессмертные объекты? :)

P.S. Написал Страуструпу, потребовал объяснений :) Он согласился, что формулировка не самая точная, предложил вариант

If a class has a pointer member, consider if it needs a user-defined or deleted destructor, copy and move;

Как по мне, разница невелика, но тем не менее... В этом плане ответ @lёxölüt ближе к реалиям, потому принимаю именно его.

Answer 1

Смысл вытекает из Правила трёх (пяти). И читать это следует группами (user-defined or deleted) и (destructor, copy and move). Т.е. любую из упомянутых функций следует либо сделать определённой пользователем, либо удалённой.

Акцент на удалённом деструкторе получается, видимо, из-за расположения этих слов рядом. То, что этот случай несколько более особенный, чем для копирования/перемещения, можно было бы отразить в исходном предложении, но тогда оно стало бы более многословным. А к чему это ведёт для объекта уже сказано в смежном ответе, да и в самом вопросе, по сути, тоже.

Стоит заметить, что при создании объекта в куче (на стеке не получится, т.к. реализация сама вставляет вызов деструктора в код), тем не менее можно избежать сомнительных утечек, достаточно использовать глобальные операторы new/delete и размещающий new:

#include <new>
struct S {
    ~S() = delete;
};
int main()
{
    void* p = ::operator new (sizeof(S)); // Выделили память
    S* s = new (p) S; // Сконструировали объект по адресу 'p'
    ::operator delete(p); // Освободили память
}
Answer 2

Единственная причина для объявления класса с удаленным деструктором, которая приходит в голову: такие объекты нельзя будет объявлять, как автоматические или статические, нельзя будет использовать в качестве подобъектов, но можно будет создавать в динамической памяти, при условии, что они не будут освобождаться, т.е. будут сознательно отправляться в memory leaks.

В чем, однако, связь с темой менеджмента ресурсов через голый указатель - не ясно. Возможно, просто непродуманная формулировка.

READ ALSO
Доступ к базе данных PostgreSQL из С++ - приложения

Доступ к базе данных PostgreSQL из С++ - приложения

Друзья! Необходимо подготовить курсовой проект по базам данныхЗадание состоит в создании базы данных на сервере PostgreSQl и клиентской части,...

169
c++, денежные системы

c++, денежные системы

есть задачка: Старая английская денежная система использует три единицы для хранения денежных величин: фунты, шиллинги и пенсыОдин фунт...

167
Вычисление количества ударов

Вычисление количества ударов

Нужно подсчитать количество потраченых ударов для убийства монстраНа вход поступают: начальный урон [d], увеличение урона при каждом ударе...

119
Что это значит `str[i]!=(char)NULL`?

Что это значит `str[i]!=(char)NULL`?

Что это значит str[i]!=(char)NULL?

136