Страницы

Поиск по вопросам

четверг, 5 декабря 2019 г.

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

#cpp #деструктор


Читаю "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 ближе
к реалиям, потому принимаю именно его.
    


Ответы

Ответ 1



Смысл вытекает из Правила трёх (пяти). И читать это следует группами (user-defined or deleted) и (destructor, copy and move). Т.е. любую из упомянутых функций следует либо сделать определённой пользователем, либо удалённой. Акцент на удалённом деструкторе получается, видимо, из-за расположения этих слов рядом. То, что этот случай несколько более особенный, чем для копирования/перемещения, можно было бы отразить в исходном предложении, но тогда оно стало бы более многословным. А к чему это ведёт для объекта уже сказано в смежном ответе, да и в самом вопросе, по сути, тоже. Стоит заметить, что при создании объекта в куче (на стеке не получится, т.к. реализация сама вставляет вызов деструктора в код), тем не менее можно избежать сомнительных утечек, достаточно использовать глобальные операторы new/delete и размещающий new: #include struct S { ~S() = delete; }; int main() { void* p = ::operator new (sizeof(S)); // Выделили память S* s = new (p) S; // Сконструировали объект по адресу 'p' ::operator delete(p); // Освободили память }

Ответ 2



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

Комментариев нет:

Отправить комментарий