Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: NaveenОтветов: 5

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

delete p;

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

delete this;

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

c++delete-operatorconstants

Ответы

Ответ 1 · рейтинг 114 · Community

Это для поддержки:

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

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

Ответ 2 · рейтинг 49 · PaulJWilliams

Скажем так: если бы это было запрещено, не было бы возможности удалить объекты const без использования const_cast.

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

Ответ 3 · рейтинг 6 · Oktalist

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

Да, вы.

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

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

Ответ 4 · рейтинг 5 · Indy9000

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

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

Ответ 5 · рейтинг 5 · Daniel Earwicker

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

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

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

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы