Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 删除指向常量(T const*)的指针_C++_Constants_Delete Operator - Fatal编程技术网

C++ 删除指向常量(T const*)的指针

C++ 删除指向常量(T const*)的指针,c++,constants,delete-operator,C++,Constants,Delete Operator,我有一个关于常量指针的基本问题。我不允许使用常量指针调用任何非常量成员函数。但是,我可以在常量指针上执行此操作: delete p; 这将调用类的析构函数,该类本质上是一个非常量“方法”。为什么允许这样做?是否只是为了支持这一点: delete this; 还是有其他原因?这是为了支持: // dynamically create object that cannot be changed const Foo * f = new Foo; // use const member funct

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

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

delete this;
还是有其他原因?

这是为了支持:

// 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对象。

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


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

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


“常量指针”是指在对象处于活动状态时对其执行操作时不会更改对象的状态。

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

如果C++中的指针表现得像弱引用,那么,一旦对象被破坏,所有现存指针立即被设置为<代码> 0 ,这种区别会更加明显。(这是在运行时被认为太昂贵的东西,它会强加给所有C++程序,实际上不可能使它完全可靠。) 更新:九年后读到这篇文章时,它是律师式的。我现在觉得你最初的反应是可以理解的。不允许突变但允许破坏显然是有问题的。常量指针/引用的隐含契约是,它们的存在将作为目标对象销毁时的一个块,即自动垃圾收集

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

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

是的,你是

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

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

const Foo* aPointerToConst = new Foo;
aPointerToConst->aNonConstMemberFunction(); // illegal
您将指向非常量对象的常量指针与指向常量对象的非常量指针混淆

话虽如此

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

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

+1以获取最新编辑信息。我认为这是真正的原因。const对象的自动析构函数调用-与delete f几乎相同;其中,f-常量上的指针。
const Foo*f
Foo const*f
不是指向Foo的常量指针。这是一个很好的例子
Foo*const f
是一个指向Foo的常量指针。析构函数可以以相当激烈的方式对对象进行变异,所以这一定是“不可变”这个词的一些奇怪用法,我以前不知道…@DarthGizka不,析构函数将你从有对象的状态带到没有对象的状态。C++没有定义任何方法来观察“突变”破坏后的@ Calth:标准可能不允许你在对象析构函数运行完成后查看它,但是你可以肯定地看到破坏造成的副作用。因此,可以很容易地安排环境,使“不可变”对象的突变可以观察到。在美国,当没有尸体时,谋杀很难起诉,但它仍然是谋杀(而且可能还有其他足以定罪的证据)。同样的差异。如果你不能破坏指针指向const的东西,你如何处理<代码> STD::UnQuyJPPT/C++ >结束它的生命?@ Caleth,那么C++中就没有解决方案了。这只是一个普通问题的例子:在C++中,const修饰符意味着“你不能改变目标,除非在某种意义上你可以完全破坏它,并使它的所有其他引用无效和未定义行为的来源”。这就是为什么我认为这样的问题应该作为一个提示来考虑其他语言。它有很多漏洞,如果不采取不同的基本方法就无法解决。