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

関数の2行目deleteMe()に到達することはありませんが、呼び出されます。それは言語の哲学に反していると思いませんか?

于 2012-08-01T09:53:03.830 に答える