Как мы можем назвать это удалением; в константной функции-члене?

Я видел следующий фрагмент кода:

class UPNumber {
public:
  UPNumber();
  UPNumber(int initValue);
  ...

  // pseudo-destructor (a const member function, because
  // even const objects may be destroyed)
  void destroy() const { delete this; } // why this line is correct???

  ...

private:
  ~UPNumber();
};

Во-первых, я уверен, что приведенное выше определение класса верно. Вот мой вопрос, почему мы можем определить функцию «уничтожить», как указано выше? Причина, по которой спрашивают, заключается в том, почему мы можем изменить 'this' в функции-члене const?


person q0987    schedule 28.02.2011    source источник


Ответы (4)


Квалификатор const, применяемый к методу, делает переданный ему this указателем const; в частности, в вашем случае это будет const UPNumber *.

Тем не менее, это не проблема для delete: на самом деле вы можете использовать delete для указателя const без необходимости приведения чего-либо, как указано в §5.3.5 ¶2:

[Примечание: указатель на константный тип может быть операндом выражения удаления; нет необходимости отбрасывать константу (5.2.11) выражения указателя до того, как оно будет использовано в качестве операнда выражения удаления. ]

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

Идея, лежащая в основе такого поведения, заключается в том, что в противном случае у вас не было бы возможности delete const объекты без использования const_cast; см. этот вопрос для получения дополнительной информации.

person Matteo Italia    schedule 28.02.2011

Это работает по той же причине, что и эта:

const int* upn = new int();
delete upn;

Вы можете delete указать указатель на константный объект. Квалификация const для функции-члена просто означает, что this имеет тип const UPNumber*.

person James McNellis    schedule 28.02.2011
comment
@James, здесь мы не можем вызвать delete upn b / c, деструктор является частным. -- Спасибо - person q0987; 01.03.2011
comment
@ q0987: Члены класса имеют доступ к закрытым членам. Функция destroy требует доступа к деструктору из-за выражения delete this и имеет доступ, потому что он является членом класса. - person GManNickG; 01.03.2011
comment
@GMan: Я думаю, OP жаловался на мой пример, который сначала использовал его класс UPNumber вместо int. - person James McNellis; 01.03.2011
comment
@James: Читая ваш код, я подумал, что вы пытаетесь сослаться на старую сеть UPN. :) - person Kredns; 09.03.2011

Откуда вы взяли, что мы модифицируем this? На самом деле this не является lvalue. Он не может быть изменен, независимо от того, является ли функция-член const или нет.

Применение delete-expression к указателю (любому указателю, а не только this) никоим образом не считается модификацией этого указателя. Более того, аргумент выражения-удаления обрабатывается как rvalue, что означает, что он не может быть изменен delete.

Итак, с этим применением delete в вашем коде проблем нет.

person AnT    schedule 28.02.2011
comment
Если я правильно понял вашу точку зрения, функция-член ТОЛЬКО обещает НЕ изменять значения, указанные this. --Спасибо - person q0987; 01.03.2011
comment
Я думаю, это больше, чем нужно сказать о том факте, что спрашивающий ошибочно написал, почему мы можем изменить 'this' в функции const-member? this. Невысказанное предположение состоит в том, что удаление объекта является формой модификации (и на самом деле это так, поскольку деструктор может изменять члены на своем выходе). - person Steve Jessop; 01.03.2011

Поскольку это технически возможно и определено для вызова delete this при условии, что вы будете осторожны, постоянство метода "suicide" технически бессмысленно, так как объект нельзя трогать после вызова.

Вот почему семантически некорректно иметь const метод, вызывающий delete this.

Интересный момент принес Комментарий Стива Джессепа. Запуск деструктора не сохраняет объект неизменным, поэтому применение концепции константности вызывает сомнения.

person Wolf    schedule 06.01.2015