Удаление указателя на const (T const *)

У меня есть основной вопрос относительно указателей const. Мне не разрешено вызывать любые не-const-функции-члены, используя указатель const. Тем не менее, я могу сделать это с помощью указателя const:

delete p;

Это вызовет деструктор класса, который по сути является неконстантным "методом". Почему это разрешено? Это только для того, чтобы поддержать это:

delete this;

Или есть еще одна причина?

Ответ 1

Он поддерживает:

// dynamically create object that cannot be changed
const Foo * f = new Foo;

// use const member functions here

// delete it
delete f;

Но обратите внимание, что проблема не ограничивается динамически создаваемыми объектами:

{
 const Foo f;
 // use it
} // destructor called here

Если деструкторы не могли быть вызваны в объектах const, мы вообще не могли бы использовать объекты const.

Ответ 2

Положите это так - если бы он не был разрешен, не было бы способа удалить объекты const без использования const_cast.

Семантически, const является признаком того, что объект должен быть неизменным. Это не означает, однако, что объект не следует удалять.

Ответ 3

Мне не разрешено вызывать любые не-константные функции-члены с помощью указателя const.

Да, вы.

class Foo
{
public:
  void aNonConstMemberFunction();
};

Foo* const aConstPointer = new Foo;
aConstPointer->aNonConstMemberFunction(); // legal

const Foo* aPointerToConst = new Foo;
aPointerToConst->aNonConstMemberFunction(); // illegal

Вы запутали указатель const неконстантного объекта с указателем, не являющимся константой, для объекта const.

Сказав, что

delete aConstPointer; // legal
delete aPointerToConst; // legal

правомерно удалять либо по причинам, уже изложенным в других ответах здесь.

Ответ 4

Конструкторы и деструкторы не должны рассматриваться как "методы". Это специальные конструкции для инициализации и срыва объекта класса.

'const pointer' указывает, что состояние объекта не будет изменено, когда операции будут выполняться на нем, пока он жив.

Ответ 5

Другой способ взглянуть на это: точный смысл указателя const заключается в том, что вы не сможете вносить изменения в объект с указателем, который будет видимым через этот или любой другой указатель или ссылку на тот же объект. Но когда объект разрушается, все остальные указатели на адрес, ранее занятый теперь удаленным объектом, больше не указывают на этот объект. Они сохраняют один и тот же адрес, но этот адрес больше не является адресом какого-либо объекта (фактически он может быть повторно использован как адрес другого объекта).

Это различие было бы более очевидным, если указатели на С++ ведут себя как слабые ссылки, т.е. как только объект будет уничтожен, все оставшиеся указатели на него сразу будут установлены на 0. (То, что считалось слишком дорогостоящим во время выполнения, чтобы навязывать все программы на С++, и на самом деле невозможно сделать его полностью надежным.)

ОБНОВЛЕНИЕ. Прочитав это через девять лет, это адвокат. Теперь я понимаю, что ваша оригинальная реакция понятна. Отказ от мутации, но допускающий разрушение, явно проблематичен. Подразумеваемый контракт указателей/ссылок const заключается в том, что их существование будет действовать как блок для уничтожения целевого объекта, автоматической сборки мусора a.k.a..

Обычным решением для этого является использование практически любого другого языка.