2

以下を考えると:

#include <iostream>
using namespace std;

class A
{
public:
    void func() {delete this;}
    A() : x(5) {cout << "ctor A" << endl;}
    ~A() {cout << "dtor A" << endl;}
    int x;
};

int main() {
    A a;
    cout << "The X value: " << a.x << endl;
    a.func();  // calling 'delete this' ->going to the dtor #1
    cout << "The X value: " << a.x << endl;
    return 0;  
}

出力は次のとおりです。

ctor A
The X value: 5
dtor A
The X value: 5
dtor A

delete this;劇的な影響はありますか?

4

5 に答える 5

5

この場合 (new 経由で A オブジェクトを割り当てていない)、未定義の動作を呼び出しています。通常、未定義の動作は非常に悪いことです。基本的に、何でも起こりえます。

「delete this;」というコードを書くことは可能です。でもいいでしょう。しかし、私はこれをしたことを思い出せません。それを避けるようにしてください。この責任を他のオブジェクト (スマート ポインターなど) に委譲することで、(new を使用したかどうかに関係なく) delete を手動で完全に呼び出さないようにしてください。

于 2011-08-28T10:19:39.897 に答える
3

deleteスタックに割り当てられたオブジェクトで呼び出していることを確認delete thisし、一般的な使用法を調べます。

「それは良い考えではない」という考え方があります。ただし、参照カウントオブジェクトの実装で何度も使用されているのを見てきました。

COMでは、フレームワークでは、すべてのオブジェクトがファクトリ メソッドによって作成され、"Release" の呼び出しによって再び解放される必要があります。

  class MyRefCountedObject : public IUnknown
  {
      private:
           // Making the constructor and destructor private
           // so that the object can only be allocated as a pointer

           MyRefCountedObject() {}

           ~MyRefCountedObject() {}

           MyRefCountedObject(const MyRefCountedObject& mrco) {}

            int _refCount;
      public:
           static MyRefCountedObject* CreateInstance()
           {
                MyRefCountedObject* pObject = new MyRefCountedObject();
                pObject->_refCount = 1;
                return pObject;
           }

           void Release()
           {
                if(--_refCount == 0)
                {
                    delete this;
                }
           };
           void AddRef()
           {
               ++_refCount;
           }
  }

注 - これは完全な実装ではなく、ロジックのアイデアを提供するだけです。しかし、コンストラクターをプライベートにすることで、これがヒープにのみ割り当てられるようにすることができます。

于 2011-08-28T10:24:50.210 に答える
3

オペレーターは、オブジェクトのdeleteデストラクタを呼び出してから、オブジェクトによって使用されている基になるメモリを解放します。メモリはオペレータによって割り当てられている必要があります。newではdelete this、削除されたオブジェクトは単に現在のオブジェクトです。構成について特別なことは何もありません。単純な C++ です。

あなたの例では、メモリはスタックからのものであるため、未定義の動作の領域に入ります(deleteオペレーターを介して割り当てられなかったオブジェクトでオペレーターを呼び出しているためnew)。

delete thisオブジェクトはそれ自身のライフタイムに責任を持つべきではないため、一般的に呼び出すのは悪い設計と見なされます。一般に、オブジェクトの作成者にその破壊の責任を負わせることがベストプラクティスと考えられています。

ただし、個人的に非常に便利だと思う状況が 1 つあります。これは、スレッドがメッセージを送信して通信している場合に発生します。この場合、メッセージがそれ自体の存続期間を担当する場合、元のスレッドがそれを担当するよりも、実際には安全で簡単に記述できます。

于 2011-08-28T10:29:20.547 に答える
2

C++ FAQ Lite: 「メンバー関数が 'これを削除' することは合法 (かつ道徳的) ですか?」

とはいえ、適切に編成されたコードでこれを使用することはめったにありません。

于 2011-08-28T10:38:56.817 に答える
0

これを行うべきではありません。それは悪いプログラミング習慣です。new を使用するオブジェクトは、delete を使用するオブジェクトである必要があります。そうしないと、混乱してメモリリークなどが発生します。

于 2011-08-28T10:19:14.167 に答える