Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.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++ 是";删去这句话;在C+中允许+;?_C++_Memory Management_New Operator_Delete Operator_Self Destruction - Fatal编程技术网

C++ 是";删去这句话;在C+中允许+;?

C++ 是";删去这句话;在C+中允许+;?,c++,memory-management,new-operator,delete-operator,self-destruction,C++,Memory Management,New Operator,Delete Operator,Self Destruction,是否允许删除此项如果delete语句是将在该类实例上执行的最后一条语句?当然,我确信this-指针表示的对象是new创建的 我在想这样的事情: void SomeModule::doStuff() { // in the controller, "this" object of SomeModule is the "current module" // now, if I want to switch over to a new Module, eg: controll

是否允许
删除此项
如果delete语句是将在该类实例上执行的最后一条语句?当然,我确信
this
-指针表示的对象是
new
创建的

我在想这样的事情:

void SomeModule::doStuff()
{
    // in the controller, "this" object of SomeModule is the "current module"
    // now, if I want to switch over to a new Module, eg:

    controller->setWorkingModule(new OtherModule());

    // since the new "OtherModule" object will take the lead, 
    // I want to get rid of this "SomeModule" object:

    delete this;
}

我可以这样做吗?

< p> C++ FAQ Lite有一个专门针对这个

的条目
我认为这句话很好地概括了这一点

只要你小心,一个物体自杀是可以的(删除这个)


是,
删除此项
已经定义了结果,只要(正如您所注意到的)您确保对象是动态分配的,并且(当然)在对象被销毁后从不尝试使用它。多年来,人们一直在问许多问题,关于标准中特别提到的
删除此项,而不是删除其他指针。这个问题的答案相当简短:它没有说什么。它只是说
delete
的操作数必须是一个表达式,用于指定指向对象或对象数组的指针。它非常详细地介绍了一些事情,比如它如何计算出要调用什么(如果有的话)释放内存的释放函数,但是关于
delete
(§[expr.delete])的整个部分没有提到
删除这个具体地说。关于析构函数的部分确实在一个地方提到了
删除该
(§[class.dtor]/13):

在虚拟析构函数的定义点(包括隐式定义(15.8)),非数组释放函数被确定为表达式delete this出现在析构函数类的非虚拟析构函数中(参见8.3.5)

这倾向于支持标准认为
删除此项的想法
是有效的——如果它是无效的,那么它的类型就没有意义了。这是标准提到的唯一地方
删除此项
<>无论如何,有些人认为<代码>删除这个< /代码>一个讨厌的黑客,并告诉任何人谁听,这是应该避免的。一个经常被引用的问题是,很难确保类的对象只被动态分配。其他人认为这是一个完全合理的习语,并且一直使用它。就个人而言,我处于中间位置:我很少使用它,但当它似乎是工作的正确工具时,请毫不犹豫地使用它

你使用这项技术的主要时间是处理一个几乎完全有生命的物体。James Kanze举的一个例子是他为一家电话公司开发的计费/跟踪系统。当你开始打电话时,会有人注意到这一点并创建一个
phone\u call
对象。从那时起,
phone\u call
对象处理电话呼叫的详细信息(在拨号时建立连接,在数据库中添加一个条目以说明呼叫何时开始,如果您进行电话会议,可能会连接更多人,等等),当最后一个通话人挂断时,
phone\u call
对象执行其最终簿记(例如,在数据库中添加一个条目,说明您何时挂断电话,以便他们可以计算您的通话时间),然后销毁自身。
phone\u call
对象的生存期取决于第一个人何时开始通话以及最后一个人何时离开通话——从系统其余部分的角度来看,它基本上是完全任意的,因此您不能将其与代码中的任何词法范围或其他顺序绑定


对于那些可能关心这种编码的可靠性的人来说:如果你打电话到欧洲的任何一个地方,从欧洲的任何一个地方打电话到欧洲的任何一个地方,都有很大的机会(至少部分地)通过代码来处理它。

如果你感到害怕,那就是一种完全合法的黑客行为:

void myclass::delete_me()
{
    std::unique_ptr<myclass> bye_bye(this);
}

注意:如果您使用的是C++11之前的编译器,您可以使用
std::auto_ptr
而不是
std::unique_ptr
,它也会做同样的事情。

您可以这样做。但是,您不能分配给此。因此,你所说的“我想改变观点”的理由似乎很值得怀疑。在我看来,更好的方法是让持有该视图的对象替换该视图


当然,您使用的是RAII对象,因此实际上根本不需要调用delete…对吗?

这是允许的(只是在那之后不要使用对象),但我不会在实践中编写这样的代码。我认为
delete this
应该只出现在调用
release
release
的函数中,看起来像:
void release(){ref--;if(ref好,在组件对象模型(COM)中)
delete此
构造可以是
Release
方法的一部分,该方法在您想要释放已获取对象时调用:

void IMyInterface::Release()
{
    --instanceCount;
    if(instanceCount == 0)
        delete this;
}

这是一个古老的、有答案的问题,但是@Alexandre问“为什么会有人想这样做?”,我想我可以提供一个我今天下午正在考虑的示例用法

遗留代码。使用裸指针Obj*Obj,末尾带有delete Obj

不幸的是,我有时需要,而不是经常需要,来让这个对象活得更长

我正在考虑让它成为一个引用计数的智能指针。但是如果我在任何地方都使用
ref\u cnt\u ptr
,那么会有很多代码需要更改。如果你混合使用裸Obj*和ref\u cnt\u ptr,你可以在最后一个ref\u cnt\u ptr消失时隐式删除对象,即使还有Obj*

因此,我正在考虑创建一个显式的_delete _ref _cnt _ptr。即一个引用计数指针,其中删除只在显式删除例程中完成。在现有代码知道对象生存期的地方使用它,以及在我的新代码中使用它,使对象保持更长的生存时间

递增和递减引用
void IMyInterface::Release()
{
    --instanceCount;
    if(instanceCount == 0)
        delete this;
}
template<typename T> class explicit_delete_ref_cnt_ptr { 
 private: 
   T* ptr;
   int rc;
   ...
 public: 
   void delete_if_rc0() {
      if( this->ptr ) {
        this->rc--;
        if( this->rc == 0 ) {
           delete this->ptr;
        }
        this->ptr = 0;
      }
    }
 };
class Pointee { 
 private: 
   int rc;
   ...
 public: 
   void delete_if_rc0() {
        this->rc--;
        if( this->rc == 0 ) {
           delete this;
        }
      }
    }
 };
map<void*,int> keepalive_map;
template<typename T>
void delete_if_rc0(T*ptr) {
        void* tptr = (void*)ptr;
        if( keepalive_map[tptr] == 1 ) {
           delete ptr;
        }
};