Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中自删除对象+;_C++ - Fatal编程技术网

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;
}