可能重复:
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 ...
并且程序正常退出,但这里有一些内存访问暴力吗?
答案 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()
函数中的第二行,但是它会被调用。难道你不认为这违背了语言的哲学吗?