我对const指针有一个基本的问题。我不允许使用const指针调用任何非const成员函数。但是,我可以在const指针上执行此操作:
delete p;
这将调用类的析构函数,它实质上是一个非const'方法'。为什么允许这样做?只是为了支持这个:
delete this;
还是有其他原因吗?
答案 0 :(得分:101)
支持:
// 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对象。
答案 1 :(得分:43)
这样说 - 如果不允许,那么在不使用const_cast的情况下就无法删除const对象。
从语义上讲,const表示对象应该是不可变的。但是,这并不意味着不应删除该对象。
答案 2 :(得分:5)
不应将构造函数和析构函数视为“方法”。它们是用于初始化和拆除类的对象的特殊构造。
'const pointer'用于指示在对象处于活动状态时对其执行操作时不会更改对象的状态。
答案 3 :(得分:4)
另一种看待它的方法:const指针的确切含义是你将无法对通过该指针或任何其他指针或对同一对象的引用可见的指向对象进行更改。但是当一个对象析构时,所有其他指向以前被当前删除的对象占用的地址的指针都不再是指向该对象的指针。它们存储相同的地址,但该地址不再是任何对象的地址(实际上它可能很快会被重用为不同对象的地址)。
如果C ++中的指针表现得像弱引用,这种区别会更明显,即一旦对象被销毁,所有现存指针都将立即设置为0
。 (那种在运行时被认为对所有C ++程序施加过高代价的事情,实际上不可能使它完全可靠。)
更新:九年后再读一遍,这是律师。我现在发现你原来的反应是可以理解的。禁止突变但允许破坏显然是有问题的。 const指针/引用的隐含契约是它们的存在将作为破坏目标对象的块,a.k.a。自动垃圾收集。
通常的解决方法是使用几乎任何其他语言。
答案 4 :(得分:4)
我不允许使用const指针调用任何非const成员函数。
是的,你是。
class Foo
{
public:
void aNonConstMemberFunction();
};
Foo* const aConstPointer = new Foo;
aConstPointer->aNonConstMemberFunction(); // legal
const Foo* aPointerToConst = new Foo;
aPointerToConst->aNonConstMemberFunction(); // illegal
你把const指针与非const对象混淆了,用一个指向const对象的非const指针。
话虽如此,
delete aConstPointer; // legal
delete aPointerToConst; // legal
删除任何一个都是合法的,原因在于此处其他答案已经说明的原因。