自我删除C ++中的对象

时间:2012-08-01 09:49:25

标签: c++

  

可能重复:
  C++: Delete this?
  Object-Oriented Suicide or delete this;

我想知道以下代码是否安全运行:

#include <iostream>
using namespace std;

class A
{
public:
    A() {
        cout << "Constructor" << endl;
    }
    ~A() {
        cout << "Destructor" << endl;
    }

    void deleteMe() {
        delete this;
        cout << "I was deleted" << endl;
    }
};

int main()
{
    A *a = new A();
    a->deleteMe();
    cout << "Exit ...";
    return 0;
}

输出是:

Constructor
Destructor
I was deleted
Exit ...

并且程序正常退出,但这里有一些内存访问暴力吗?

5 个答案:

答案 0 :(得分:9)

delete this没关系,以防在调用后没有人使用该对象。如果对象是在一堆当然分配

例如cocos2d-x游戏引擎就是这样做的。它使用与Objective-C相同的内存管理方案,这是一个基础对象的方法:

void CCObject::release(void)
{
    CCAssert(m_uReference > 0, "reference count should greater than 0");
    --m_uReference;

    if (m_uReference == 0)
    {
        delete this;
    }
}

我不认为这是管理记忆的c++方式,但它可能

答案 1 :(得分:1)

没关系,因为你有简单的方法。删除后,所有变量和虚拟表都清晰。只是,分析这个例子:

#include <iostream>

class foo
{
public:
    int m_var;
    foo() : m_var(1)  
    {

    }

    void deleteMe()
    {
        std::cout << m_var << "\n";
        delete this;
        std::cout << m_var << "\n"; // this may be crush program, but on my machine print "trash" value, 64362346 - for example
    }

    virtual void bar()
    {
        std::cout << "virtual bar()\n";
    }



  void anotherSimpleMethod()
    {
       std::cout << "anotherSimpleMethod\n";
    }

    void deleteMe2()
    {
        bar();
        delete this;
        anotherSimpleMethod();
        // bar(); // if you uncomment this, program was crashed, because virtual table was deleted
    }
};

int main()
{
    foo * p = new foo();
    p->deleteMe();
    p = new foo();
    p->deleteMe2();
    return 0;
}

我无法解释更多细节,因为它需要一些关于在加载程序后在RAM中存储类和方法的知识。

答案 2 :(得分:0)

绝对,你只是运行析构函数。方法不属于对象,因此运行正常。在外部上下文中,对象(* a)将被销毁。

答案 3 :(得分:0)

如果怀疑在内存使用(或类似问题)方面发生的奇怪事情是否依赖于正确的分析工具来帮助您澄清情况。

例如,使用valgrind或类似的程序来检查是否存在内存泄漏或类似问题,编译器几乎无法帮助您。

虽然每种工具都有其局限性,但通常可以通过使用它来获得一些有价值的见解。

答案 4 :(得分:-1)

其中没有内存访问冲突,您只需要小心。但是,任何语言都不建议删除this指针,即使上面的代码可以正常工作。因为它与delete a相同,但尝试以其他方式,安全的方式。

例如,您发布的代码本身就存在不合逻辑的内容。

void deleteMe() 
{
    delete this;
    cout << "I was deleted" << endl; // The statement here doesn't make any sense as you no longer require the service of object a after the delete operation 
}

编辑: Sjoerd

这样做更有意义

 void deleteMe() 
{
    delete this;
}

 int main()
 {
 A *a = new A();
 a->deleteMe();
 cout << "a was deleted" << endl;
 cout << "Exit ...";
 return 0;
 }

永远不应该到达deleteMe()函数中的第二行,但是它会被调用。难道你不认为这违背了语言的哲学吗?