是否允许删除这个;如果删除语句是将在该类实例上执行的最后一条语句?当然,我确定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;
}

我能这样做吗?


当前回答

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

其他回答

One of the reasons that C++ was designed was to make it easy to reuse code. In general, C++ should be written so that it works whether the class is instantiated on the heap, in an array, or on the stack. "Delete this" is a very bad coding practice because it will only work if a single instance is defined on the heap; and there had better not be another delete statement, which is typically used by most developers to clean up the heap. Doing this also assumes that no maintenance programmer in the future will cure a falsely perceived memory leak by adding a delete statement.

Even if you know in advance that your current plan is to only allocate a single instance on the heap, what if some happy-go-lucky developer comes along in the future and decides to create an instance on the stack? Or, what if he cuts and pastes certain portions of the class to a new class that he intends to use on the stack? When the code reaches "delete this" it will go off and delete it, but then when the object goes out of scope, it will call the destructor. The destructor will then try to delete it again and then you are hosed. In the past, doing something like this would screw up not only the program but the operating system and the computer would need to be rebooted. In any case, this is highly NOT recommended and should almost always be avoided. I would have to be desperate, seriously plastered, or really hate the company I worked for to write code that did this.

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

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

c++ FAQ Lite中有一个专门的条目

https://isocpp.org/wiki/faq/freestore-mgmt#delete-this

我认为这句话很好地总结了这一点

只要你小心,对象自杀是可以的(删除这个)。

这是引用计数对象的核心习惯用法。

引用计数是一种强大的确定性垃圾收集形式——它确保对象管理自己的生命周期,而不是依赖“智能”指针等来为它们做这些。底层对象只能通过“Reference”智能指针访问,设计为指针在实际对象中递增或递减一个成员整数(引用计数)。

当最后一个引用退出堆栈或被删除时,引用计数将归零。对象的默认行为将是调用“delete this”来进行垃圾收集——我写的库在基类中提供了一个受保护的虚拟“CountIsZero”调用,这样你就可以为缓存之类的事情覆盖这个行为。

确保安全的关键是不允许用户访问相关对象的构造函数(使其受保护),而是让他们调用一些静态成员——FACTORY——比如“static Reference CreateT(…)”。通过这种方式,你可以确定它们总是用普通的“new”构建的,并且没有原始指针可用,所以“delete this”永远不会爆炸。

Yes, delete this; has defined results, as long as (as you've noted) you assure the object was allocated dynamically, and (of course) never attempt to use the object after it's destroyed. Over the years, many questions have been asked about what the standard says specifically about delete this;, as opposed to deleting some other pointer. The answer to that is fairly short and simple: it doesn't say much of anything. It just says that delete's operand must be an expression that designates a pointer to an object, or an array of objects. It goes into quite a bit of detail about things like how it figures out what (if any) deallocation function to call to release the memory, but the entire section on delete (§[expr.delete]) doesn't mention delete this; specifically at all. The section on destructors does mention delete this in one place (§[class.dtor]/13):

在定义虚析构函数时(包括隐式定义(15.8)),非数组释放函数的确定就像表达式delete this出现在析构函数类的非虚析构函数中一样(参见8.3.5)。

这倾向于支持标准考虑删除这个的想法;如果它是无效的,它的类型就没有意义。这是标准中唯一提到删除的地方;据我所知,根本没有。

不管怎样,有些人认为删除这条消息是一种恶意攻击,并告诉任何愿意听的人应该避免这样做。一个经常被引用的问题是很难确保类的对象只被动态分配。其他人认为这是一个非常合理的习语,并一直在使用它。就我个人而言,我介于两者之间:我很少使用它,但当它似乎是适合这项工作的工具时,不要犹豫。

The primary time you use this technique is with an object that has a life that's almost entirely its own. One example James Kanze has cited was a billing/tracking system he worked on for a phone company. When you start to make a phone call, something takes note of that and creates a phone_call object. From that point onward, the phone_call object handles the details of the phone call (making a connection when you dial, adding an entry to the database to say when the call started, possibly connect more people if you do a conference call, etc.) When the last people on the call hang up, the phone_call object does its final book-keeping (e.g., adds an entry to the database to say when you hung up, so they can compute how long your call was) and then destroys itself. The lifetime of the phone_call object is based on when the first person starts the call and when the last people leave the call -- from the viewpoint of the rest of the system, it's basically entirely arbitrary, so you can't tie it to any lexical scope in the code, or anything on that order.

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