是否允许删除这个;如果删除语句是将在该类实例上执行的最后一条语句?当然,我确定this指针所表示的对象是新创建的。

我在想这样的事情:

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;
}

我能这样做吗?


当前回答

好吧,在组件对象模型(COM)中,删除这个结构可以是Release方法的一部分,当你想释放被获取的对象时,它会被调用:

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

其他回答

你可以这样做。然而,你不能给它赋值。因此,你陈述这样做的原因,“我想改变观点”,似乎很有问题。在我看来,更好的方法是让持有视图的对象替换该视图。

当然,你使用的是RAII对象所以你根本不需要调用delete,对吧?

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

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

不幸的是,我有时需要,而不是经常,让对象活得更久。

我正在考虑使它成为一个引用计数智能指针。但会有很多代码要改变,如果我是使用ref_cnt_ptr<Obj>无处不在。如果你混合裸Obj*和ref_cnt_ptr,当最后一个ref_cnt_ptr消失时,你可以隐式删除对象,即使Obj*仍然存在。

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

在操作explicit_delete_ref_cnt_ptr时增加或减少引用计数。

但当在explicit_delete_ref_cnt_ptr析构函数中看到引用计数为零时,则不释放。

仅当在显式删除类操作中看到引用计数为零时才释放。例如:

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;
      }
    }
 };

好吧,就像这样。引用计数指针类型不会自动删除rc'ed ptr析构函数中所指向的对象,这有点不寻常。但这似乎可以使混合裸指针和rc'ed指针更安全一些。

但到目前为止还不需要删除这个。

但后来我想到:如果被指向的对象,被指针,知道它被引用计数,例如,如果计数在对象内部(或在其他一些表中),那么例程delete_if_rc0可能是被指针对象的一个方法,而不是(智能)指针。

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;
        }
};

(顺便说一句,我知道代码不太正确-如果我添加所有的细节,它变得不那么可读,所以我就这样留下它。)

这是允许的(只是在那之后不要使用对象),但我不会在实践中编写这样的代码。我认为delete this应该只出现在调用release或release的函数中,看起来像:void release() {ref——;If (ref<1);}。

只要对象在堆中,删除是合法的。 您需要要求对象仅为堆。 做到这一点的唯一方法是使析构函数受保护——这种方法可以从类中only调用delete,因此您需要一个方法来确保删除

如果你害怕,有一个完全合法的破解方法:

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

我认为删除它是c++的惯用方法,我只是把它作为一种好奇来展示。

在某些情况下,这个构造实际上是有用的——您可以在抛出需要该对象成员数据的异常后删除该对象。对象在发生抛出之前一直有效。

void myclass::throw_error()
{
    std::unique_ptr<myclass> bye_bye(this);
    throw std::runtime_exception(this->error_msg);
}

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