14

可能重复:
C++:删除这个?
面向对象自杀或删除此;

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

#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 ...

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

4

5 回答 5

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++管理内存的方式,但这是可能的

于 2012-08-01T09:50:20.147 回答
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 中的知识。

于 2012-08-01T11:38:33.430 回答
0

当怀疑内存使用(或类似问题)方面是否发生了奇怪的事情时,请依靠适当的分析工具来帮助您澄清情况。

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

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

于 2012-08-01T10:06:59.133 回答
0

当然,您只需运行析构函数。方法不属于对象,所以运行正常。在外部上下文中,对象 (*a) 将被销毁。

于 2012-08-01T09:55:16.383 回答
-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()永远不要到达函数中的第二行,但它会被调用。你不认为这违背了语言的哲学吗?

于 2012-08-01T09:53:03.830 回答