void operator delete (void*);
...
const char *pn = new char, *pm = (char*)malloc(1);
delete pn; // allowed !!
free(pm); // error
free()
是一个函数是可以理解的,因此const void*
无法转换为void*
。但是为什么在operator delete
(默认或重载)的情况下允许它?
它在功能上是不是错误的构造?
答案 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。