为什么在“operator delete”中将“const T *”简单地转换为“void *”?

时间:2011-11-15 14:30:30

标签: c++ pointers const free delete-operator

  

可能重复:
  Deleting a pointer to const (T const*)

void operator delete (void*);
...
const char *pn = new char, *pm = (char*)malloc(1);
delete pn; // allowed !!
free(pm); // error

Demo

free()是一个函数是可以理解的,因此const void*无法转换为void*。但是为什么在operator delete(默认或重载)的情况下允许它?

它在功能上是不是错误的构造?

2 个答案:

答案 0 :(得分:4)

不是。 delete表达式首先调用析构函数。 破坏,你留下void*。 (典型的实施, 事实上,析构函数调用operator delete()函数,因为 调用operator delete()取决于派生类最多的类。)

至于为什么你的T const*在析构函数中成为T*:这就是任何问题 不同于:

{
    T const anObject;
    //  ...
} // destructor of anObject called here.  With T*, not T const*

?人们可以争论不同的规则,但最终,析构者是 特别的,并遵守特殊规则。

答案 1 :(得分:2)

虽然我非常同意@ JamesKanze的回答,但也许有人想看看标准实际上说的是什么。根据标准(§12.1/ 4):

  

const和volatile语义(7.1.5.1)不适用于对象下   施工。这种语义只有在派生对象最多的构造函数(1.8)后才生效   结束。

和(§12.4/ 2):

  

const和   volatile asmantics(7.1.5.1)不适用于破坏对象。这种语义不再存在   一旦最派生对象(1.8)的析构函数开始,它就会生效。

公平地说,这只不过是重新陈述@James所说的内容,更具体一点:对象只是在ctor完成时才真正被视为对象(或 all ctors ,当涉及继承时)到第一个dtor开始的点。在这些边界之外,不执行const和volatile。