5

重複の可能性:
C ++:これを削除しますか?
オブジェクト指向の自殺またはこれを削除します。

私は非常に優れた本C++Primerを読んでC++を学んでおり、C++がdeleteCのようにキーワードによってメモリの割り当てを解除する方法を学んでいfreeます。JavaとPascalには、メモリを明示的に解放するためのこのメカニズムはありません。プログラムが長時間実行され、必要な変数が破棄されると、プログラムでエラーが発生する可能性があるため、些細なことではありません。

要するに、たとえばC ++で、変数がそれ自体this.delete()を実行および削除することは合法であるか、または推奨されるのでしょうか。私たちは主にCとC++でポインタを解放することについて耳にしますが、これはnewとkeywordsで行われます。Pascalにもポインタがありますが、Javaにはありません。したがって、Javaでは、オブジェクトを明示的に削除しないため、Cにはオブジェクトがないため、Cにはオブジェクトがなく、Pascalにもオブジェクトがないため、技術的に可能であったとしても、割り当てられたメモリを使用できません。freedeletestructfree

だから私は、オブジェクトが次のようなものでそれ自体を削除することが合法であるかどうかという私の質問のためにC++を残すと思いますthis.delete()か?

4

6 に答える 6

6

オブジェクトが行うことは完全に可能ですdelete this;

ただし、そうした後の使用thisは未定義の動作です。

したがって、後で行われることに非常に注意を払う場合、オブジェクトが行うことによって「自殺」することは問題なく合法です。delete this;

ただし、これは実際には良い考えではありません。特に、スタックに割り当てるとデストラクタが2回呼び出される可能性があるため、クラスはnewによってのみインスタンス化される必要があるためです。これを削除する場合と、コンテキストから外れる場合です。

次の例は、それが適切でない理由を示しています。

class A
{
public:
    ~A() { std::cout << "Destructor"; }
    void foo() { delete this; } 
};

int main()
{
    {
        A a;
        a.foo(); // OK, a is deleted
    } // Going out of context, the destructor is called again => undefined behavior
    return 0;
}
于 2012-05-28T10:58:31.803 に答える
5

this ポインタです適切な構文は次のようになります

 delete this;

はい、可能ですが、オブジェクトとオブジェクトへのポインタが使用できなくなります。

よく読むためにこれを参照してください。

実際には、何をしているのか完全に確信が持てない限り、この手法を使用することはコードの臭いです。

于 2012-05-28T10:58:19.743 に答える
3

オブジェクトがthis.delete()のようなもので自分自身を削除することが合法かどうかという私の質問ですか?

技術的には、オブジェクトが実行することは合法ですdelete thisただし、 FAQで説明されている非常に重要な警告がいくつかあります。

delete thisそれが非常に狭い技術的問題を解決することを理解することも重要です。これは、メモリ管理とガベージコレクションに関する全体像の質問を実際には解決しません。さらに研究する価値のある1つの方向は、C++でのスマートポインターの使用です

于 2012-05-28T10:59:05.517 に答える
0

奇妙な1つの使用例は、ユーザーが[OK]などをクリックするダイアログボックスの場合です。このアクションにより、ダイアログボックスは自動的に削除されますが、これは有効です。

もちろん、thisポインタはもう有効ではないので、使用しないでください。

于 2012-05-28T10:59:45.313 に答える
0

オブジェクトが自身のメモリの割り当てを解除することは完全に可能です。ただし、明らかな理由から、使用されることはめったにありません。

最も一般的な使用法は、参照カウントメモリ管理を実装することです。呼び出し元が呼び出しrelease()て参照カウントがゼロになると、オブジェクトは削除されます。これはメンバー変数内で発生するため、ポインターを使用してインスタンスを削除します(オブジェクトの外部でthis呼び出すのとほぼ同じ方法です)。delete foo例えば:

int release()
{
    OSAtomicDecrement32(&m_refCount);
    if (m_refCount <= 0)
    {
        delete this;
    }
    return m_refCount;
}

(あなたが言及した構文は無効であることに注意してください-deleteはキーワードであり、メソッドではなくthis、ポインターです。)

ただし、覚えておくべきいくつかの注意事項があります。この削除が呼び出されると、thisポインターは無効になり、データメンバーも無効になります。その時点から、インスタンス以外の参照のみを行うことができます(たとえば、ローカル変数、静的メソッド、データなど)。

于 2012-05-28T11:05:13.190 に答える
0

オブジェクトがそのメモリを削除する別の方法は、Resource AquisitionIsInitialisationと呼ばれるものを使用することです。RAII

このメソッドでは、オブジェクトを実行しnewません。deleteデストラクタは、スコープを離れると自動的に呼び出されます。

つまりRAII、次のような関数で使用します。

void foo()

{

  `Object a;`

  `int i = a.SomeMethod();`

  `// a's destructor automatically gets called when the function is out of scope`

}

参考文献

于 2012-05-28T11:11:09.163 に答える