删除指向 const 的指针 (T const*)

发布于 2024-07-16 13:48:29 字数 240 浏览 6 评论 0原文

我有一个关于 const 指针的基本问题。 我不允许使用 const 指针调用任何非常量成员函数。 但是,我可以在 const 指针上执行此操作:

delete p;

这将调用该类的析构函数,该类本质上是一个非常量“方法”。 为什么这是允许的? 仅仅是为了支持这一点:

delete this;

还是还有其他原因?

I have a basic question regarding the const pointers. I am not allowed to call any non-const member functions using a const pointer. However, I am allowed to do this on a const pointer:

delete p;

This will call the destructor of the class which in essence is a non-const 'method'. Why is this allowed? Is it just to support this:

delete this;

Or is there some other reason?

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

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

发布评论

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

评论(5

关于从前 2024-07-23 13:48:29

它是为了支持:

// dynamically create object that cannot be changed
const Foo * f = new Foo;

// use const member functions here

// delete it
delete f;

但请注意,问题不仅限于动态创建的对象:

{
 const Foo f;
 // use it
} // destructor called here

如果无法在 const 对象上调用析构函数,我们根本无法使用 const 对象。

It's to support:

// dynamically create object that cannot be changed
const Foo * f = new Foo;

// use const member functions here

// delete it
delete f;

But note that the problem is not limited to dynamically created objects:

{
 const Foo f;
 // use it
} // destructor called here

If destructors could not be called on const objects we could not use const objects at all.

丑疤怪 2024-07-23 13:48:29

这么说吧 - 如果不允许的话,就无法在不使用 const_cast 的情况下删除 const 对象。

从语义上讲,const 表示对象应该是不可变的。 但是,这并不意味着不应删除该对象。

Put it this way - if it weren't allowed there would be no way to delete const objects without using const_cast.

Semantically, const is an indication that an object should be immutable. That does not imply, however, that the object should not be deleted.

甜中书 2024-07-23 13:48:29

构造函数和析构函数不应被视为“方法”。 它们是用于初始化和拆除类对象的特殊构造。

“常量指针”是指在对象存活期间对其进行操作时,其状态不会改变。

Constructors and Destructors should not be viewed as 'methods'. They are special constructs to initialise and tear down an object of a class.

'const pointer' is to indicate that the state of the object would not be changed when operations are performed on it while it is alive.

堇年纸鸢 2024-07-23 13:48:29

我不允许使用 const 指针调用任何非常量成员函数。

是的,你是。

class Foo
{
public:
  void aNonConstMemberFunction();
};

Foo* const aConstPointer = new Foo;
aConstPointer->aNonConstMemberFunction(); // legal

const Foo* aPointerToConst = new Foo;
aPointerToConst->aNonConstMemberFunction(); // illegal

您混淆了指向非常量对象的 const 指针和指向 const 对象的非常量指针。

话虽如此,

delete aConstPointer; // legal
delete aPointerToConst; // legal

出于此处其他答案已经说明的原因,删除其中任何一个都是合法的。

I am not allowed to call any non-const member functions using a const pointer.

Yes you are.

class Foo
{
public:
  void aNonConstMemberFunction();
};

Foo* const aConstPointer = new Foo;
aConstPointer->aNonConstMemberFunction(); // legal

const Foo* aPointerToConst = new Foo;
aPointerToConst->aNonConstMemberFunction(); // illegal

You have confused a const pointer to a non-const object, with a non-const pointer to a const object.

Having said that,

delete aConstPointer; // legal
delete aPointerToConst; // legal

it's legal to delete either, for the reasons already stated by the other answers here.

话少情深 2024-07-23 13:48:29

另一种看待它的方式:const 指针的精确含义是,您将无法对通过该指针或任何其他指针或对同一对象的引用可见的所指向的对象进行更改。 但是,当对象析构时,指向现在已删除的对象先前占用的地址的所有其他指针都不再是指向该对象的指针。 它们存储相同的地址,但该地址不再是任何对象的地址(事实上,它可能很快就会被重用为不同对象的地址)。

如果 C++ 中的指针表现得像弱引用,即一旦对象被销毁,所有现有的指向它的指针将立即被设置为0,那么这种区别将更加明显。 (这种事情被认为在运行时成本太高,无法强加在所有 C++ 程序上,而且事实上不可能使其完全可靠。)

更新:九年后读到这里,它是律师风格。 我现在发现你最初的反应是可以理解的。 不允许突变但允许破坏显然是有问题的。 const 指针/引用的隐含契约是它们的存在将充当目标对象销毁的块,即自动垃圾收集。

通常的解决方案是使用几乎任何其他语言。

Another way to look at it: the precise meaning of a const pointer is that you will not be able to make changes to the pointed-to object that would be visible via that or any other pointer or reference to the same object. But when an object destructs, all other pointers to the address previously occupied by the now-deleted object are no longer pointers to that object. They store the same address, but that address is no longer the address of any object (in fact it may soon be reused as the address of a different object).

This distinction would be more obvious if pointers in C++ behaved like weak references, i.e. as soon as the object is destroyed, all extant pointers to it would immediately be set to 0. (That's the kind of thing considered to be too costly at runtime to impose on all C++ programs, and in fact it is impossible to make it entirely reliable.)

UPDATE: Reading this back nine years later, it's lawyer-ish. I now find your original reaction understandable. To disallow mutation but allow destruction is clearly problematic. The implied contract of const pointers/references is that their existence will act as a block on destruction of the target object, a.k.a. automatic garbage collection.

The usual solution to this is to use almost any other language instead.

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