free
не должен использоваться с реальными объектами C ++. free
следует использовать с malloc
, поэтому вы не должны использовать free
для чего-то, что выделено с new
.
Относительно того, почему вы можете delete
const объекты, это просто:
const Type *ptr = new Type(...);
И что теперь? Если вы не можете это удалить, вам придется сделать следующее:
delete const_cast<Type*>(ptr);
Наличие объекта const
означает, что его нельзя изменить. Вы не можете заставить объект перейти из одного состояния в другое. Удаление выбрасывает это. Это означает, что он больше не существует в любом состоянии, будь то оригинальная или какая-либо другая измененная форма. Удаление - это операция, которая существует вне состояния изменчивости объекта, очень похоже на конструкцию.
Концептуально удаление не является ни постоянным, ни неконстантным. В то время как деструктор является неконстантной функцией, идея разрушения объекта просто находится вне области констант или неконстант.
ОК, допустим, вы определили operator delete
, чтобы взять указатель на const (который отличается от указателя const) :
void operator delete(void const* p);
Какой будет первая строка этой функции? Цель operator delete
- освободить память, выделенную operator new
. Это потребует тыкать в биты в куче выделения памяти. И для этого вам нужен указатель, который не указывает на постоянные данные:
void *ptr = const_cast<void*>(p);
Добро пожаловать в неопределенное поведение . Хотя C ++ позволяет вам делать это, в спецификации совершенно ясно, что результаты попытки записи в ptr
(или любой адрес на его основе) равны undefined . Вам дали указатель const; внешний мир сказал вам не изменять то, на что он указывает. C ++ не дает никаких гарантий относительно того, что произойдет, когда вы нарушите этот контракт.
Поскольку в спецификации указано, что это неопределенное поведение, и поскольку operator delete
(в большинстве случаев) не может выполнить свою работу без , не изменив память, на которую указывает p
(или не изменив память на основе этого адрес), было бы глупо из спецификации, чтобы затем позволить вам определить operator delete
таким образом. Это было бы в основном канонизацией идеи стрелять себе в ногу.
Да, практически в каждом случае это было бы абсолютно безопасно. Но так как вы все равно собираетесь отбросить константу, зачем вообще пытаться разрешить довольно сомнительную идею?