До вчерашнего дня был убежден, что язык не разрешает вызывать delete для указателя на const-объект. Оказалось, что ошибался. Вот такая программа успешно компилируется и запускается:
class A {}; void bar( const A * p ) { delete p; } int main() { bar( new A() ); } |
Кто-нибудь может объяснить, почему это возможно? Upd. Спасибо, объяснение получено, см. ниже.
Лично я очень удивлен по двум причинам:
Во-первых, указатель на const-объект, это read-only view на объект. И когда посредством read-only view объект уничтожается вообще, то это, по меньшей мере, неожиданно.
Во-вторых, через указатель на const-объект компилятор позволяет вызывать только const-методы объекта. Но деструктор не является таким методом с формальной точки зрения.
Соответственно, я не припомню, чтобы видел где-то в "дикой природе" уничтожение объекта через указатель на const. Если кто-то из читателей видел, то подскажите, где на это можно посмотреть, пожалуйста.
А вот и ответ на мой вопрос на stackoverflow.
Это необходимо, чтобы можно было делать так:
void foo() { const A * p = new const A(); delete p; } |
В принципе, вещь для меня неожиданная. Это если говорить о конкретных типах. Но вот если речь заходит о шаблонах, тогда все становится на свои места.
template< class T > void some_common_action() { T * p = new T(); // do something... delete p; } |
Здесь в качестве T для some_common_action может быть как просто A, так и const A. Причем тип аргумента при обращении к some_common_action может выводиться в каком-то другом, возможно совсем нетривиальном шаблоне. Поэтому для шаблонов возможность применения delete к указателю на const выглядит разумной.
Другое дело, что теперь нужно внимательнее относиться к функциям, которые в качестве аргумента принимают const T *. Вдруг ее разработчику взбредет в голову вызвать delete для аргумента. А я ни сном, ни духом :)
Комментариев нет:
Отправить комментарий