#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: #includestruct S { ~S() = delete; }; int main() { void* p = ::operator new (sizeof(S)); // Выделили память S* s = new (p) S; // Сконструировали объект по адресу 'p' ::operator delete(p); // Освободили память } Ответ 2
Единственная причина для объявления класса с удаленным деструктором, которая приходит в голову: такие объекты нельзя будет объявлять, как автоматические или статические, нельзя будет использовать в качестве подобъектов, но можно будет создавать в динамической памяти, при условии, что они не будут освобождаться, т.е. будут сознательно отправляться в memory leaks. В чем, однако, связь с темой менеджмента ресурсов через голый указатель - не ясно. Возможно, просто непродуманная формулировка.
Комментариев нет:
Отправить комментарий