2009-04-16 3 views
72

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

delete p; 

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

delete this; 

Или есть какая-то другая причина?

ответ

90

Это поддержать:

// 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 

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

+17

+1 для получения последних изменений. Я думаю, что это настоящая причина. Автоматический вызов деструктора для объекта const - почти такой же, как delete f; где f - указатель на const. – bayda

37

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

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

+0

Деструкторы могут мутировать объекты довольно жестокими способами, поэтому это должно быть какое-то странное использование слова «неизменяемое», о котором я ранее не знал ... – DarthGizka

5

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

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

4

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

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

6

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

Да, вы есть.

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

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

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

Вы спутали константный указатель на неконстантный объект, с неконстантным указателем на константный объект.

Сказав, что,

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

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