C++ 在C+中自删除对象+;
可能重复:C++ 在C+中自删除对象+;,c++,C++,可能重复: 我想知道下面的代码是否安全运行: #include <iostream> using namespace std; class A { public: A() { cout << "Constructor" << endl; } ~A() { cout << "Destructor" << endl; } void deleteMe() {
我想知道下面的代码是否安全运行:
#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;
}
程序正常退出,但这里是否存在内存访问暴力?可以删除此文件,以防调用后没有人使用该对象。当然,如果对象是在堆上分配的 例如,
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++
方法,但它可能没有内存访问冲突,您只需要小心。但是在任何语言中都不建议删除这个指针,即使上面的代码可以正常工作。因为这与删除一个
相同,但请尝试以另一种安全的方式执行
例如,您发布的代码本身有一些不合逻辑的地方
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
}
void deleteMe()
{
删除此项;
当然,您只需运行析构函数。方法不属于对象,因此它运行正常。在外部上下文中,对象(*a)将被销毁。如果怀疑内存使用方面是否有奇怪的事情发生(或类似问题),请依靠适当的分析工具来帮助您澄清情况
例如,使用或类似的程序来检查是否有内存泄漏或类似的问题,编译器很难帮助您
虽然每种工具都有其局限性,但使用它通常可以获得一些有价值的见解。这没关系,因为您已经运行了简单的方法。删除此方法后,所有变量和虚拟表都将被清除。只需分析此示例:
#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;
}
#包括
福班
{
公众:
int m_var;
foo():m_变量(1)
{
}
void deleteMe()
{
std::cout Related:Summary:这里没问题,只要你小心(不要删除没有分配给new
的东西,不要在对象被破坏后使用它)。@RobertoWilko:我的代码是用Visual Studio+Visual Assistant格式化的,我不知道这是否错了:-(如果我没记错的话,DirectX库中也使用这种方式。当您想删除一个对象并释放其内存时,可以调用SomeObj::Release()它的工作方式与您所发布的代码类似。“行”代码> CUT@ B.NHNGEYAN:我想是的,因为您不使用该对象,但我希望打印Befe<代码>消息。在任何情况下删除这个< /代码>,在COM的代码> iNo::Relabase[()] /代码>中使用相同的模式,参见“我不认为它是管理内存的C++方式”。:这取决于对象在应用程序中的角色(以及应用程序的类型)。对于许多面向对象的应用程序,删除对象的方式通常都是这样。(我同意Andrew关于在删除前打印的评论。)-1:关于“这一行永远不会到达”的废话你不了解全部情况。当然它会被执行。但是再看一次我的帖子,你可能会明白:你自相矛盾:“这一行永远不会到达”,但“它当然会被执行”。你是说这是一个编译器错误吗?!你说“ofc在函数体放在main中时执行它”是什么意思?为什么main()
在这种情况下应该是特殊的?其次,函数体是在类定义中内联定义的,而不是放在main中。如果您的意思是它可能会内联,那是真的,但是内联与否与此代码是否安全无关。Re:“调用其成员函数的对象已不复存在,其成员函数也应如此”——这完全是胡说八道。对象的非静态数据与访问它的任何代码(包括成员函数)完全分离,而销毁一个对象只会销毁该数据。只要不访问被销毁的对象,代码仍然存在,仍然是可执行的,并且仍然是定义良好的。
void deleteMe()
{
delete this;
}
int main()
{
A *a = new A();
a->deleteMe();
cout << "a was deleted" << endl;
cout << "Exit ...";
return 0;
}
#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;
}