为什么要使用“const T*”?简单地转换为“void*”在“操作员删除”中?

发布于 2024-12-16 14:38:51 字数 601 浏览 5 评论 0 原文

可能的重复:
删除指向 const (T const*) 的指针

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(默认或重载)的情况下允许它呢?

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

Possible Duplicate:
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.

It's understandable that free() is a function, so a const void* cannot be converted to void*. But why is it allowed in the case of operator delete (default or overloaded) ?

Is it not functionally a wrong construct ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嘿看小鸭子会跑 2024-12-23 14:38:51

它不是。 delete 表达式首先调用析构函数。 之后
销毁后,您将留下一个 void*。 (典型的实现,
事实上,析构函数调用了operator delete()函数,因为
调用哪个operator delete()取决于最底层的派生类。)

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

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

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

It's not. The delete expression first calls the destructor. After
destruction, you are left with a void*. (The typical implementation,
in fact, has the destructor call the operator delete() function, since
which operator delete() to call depends on the most derived class.)

As to why your T const* becomes a T* in the destructor: is this any
different than:

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

? One can argue for different rules, but in the end, destructors are
special, and obey special rules.

无悔心 2024-12-23 14:38:51

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

const 和 volatile 语义 (7.1.5.1) 不适用于以下对象:
建造。这种语义仅在最派生对象的构造函数出现后才生效(1.8)
结束。

和(§12.4/2):

常量和
易失性语义 (7.1.5.1) 不适用于正在被破坏的对象。这样的语义不再是
一旦最底层派生对象 (1.8) 的析构函数启动,就会生效。

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

While I quite agree with @JamesKanze's answer, perhaps somebody would like to see what the standard actually says. According to the standard (§12.1/4):

const and volatile semantics (7.1.5.1) are not applied on an object under
construction. Such semantics only come into effect once the constructor for the most derived object (1.8)
ends.

and (§12.4/2):

const and
volatile semantics (7.1.5.1) are not applied on an object under destruction. Such semantics stop being
into effect once the destructor for the most derived object (1.8) starts.

In fairness, this does little more than re-state what @James said, a bit more specifically: the object is only really considered an object from the time the ctor finishes (or all the ctors, when inheritance is involved) to the point that the first dtor begins. Outside those boundaries, const and volatile aren't enforced.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文