2011-06-29 15 views
2

私はそれがいつ削除されるべきかを知っている1つのクラス(A)を持っています。私はオブジェクトが自分自身を直接削除することはできないと考えています(つまり、内部からデストラクタを呼び出すことはできません)ので、コールバックを使用しました。ここでコールバックを持つ別のオブジェクトが所有するオブジェクトを、削除するオブジェクトから削除できますか?

は私の現在のソリューションの擬似コードです:

class A { 
    Owner* owner; // is set in constructor 

    A(Owner* ow) : owner(ow) {} 
    void willDeleteOurself() { 
    owner->deleteObject(); 
    } 
} 

class Owner { 
    A* obj; 

    Owner() { // e.g. constructor 
    obj = new A(this); 
    } 

    void deleteObject() { 
    delete obj; 
    } 
} 

私はクラスAのオブジェクトを所有するクラスOwnerのオブジェクトを持っています。さて、ある時点で、objは削除すべきであることを知っており、willDeleteOurself()の呼び出しが発生します。このコードはうまくいくようです。

は今、私の質問はこれです:これはobjを削除する安全な方法ですか?

ときの方法deleteObjectリターンが(}に到達した)ので、私は心配だけど、それがバックwillDeleteOurself()の終わりにジャンプしますが、その方法はそこからオブジェクトが破棄されていると呼ばれていました。

owner->deleteObject();の呼び出し後にobjを参照する文がなくなると、この構文は安全ですか?

更新:回答を

感謝。私はここで少し簡略化した。私はA* obj;を持っていませんが、オブジェクトへのブーストsmartpointer(単独で、時にはマップ内)。私はラップされたオブジェクトのdelete thisを呼び出すと、smartpointerは基になるオブジェクトが削除されたことを認識しません。あれは正しいですか?

delete this(上記のコードも)は「危険」ですが、私の問題を解決する安全な方法はありますか?

答えて

4

オブジェクトが直接オブジェクトは、あなたがいないdelete自体オブジェクトが削除された後の任意のメンバにアクセスしないように注意する必要がありますが、そこにあることができる理由は特に理由はありませんそれ自体

を削除することはできませんそれが意味を成す状況。

私はスレッドやタイマーをカプセル化しているいくつかの火災と忘れオブジェクトでこれを行っています。実際にが他のオブジェクトによって所有されたではないため、動的に作成され、が作業を完了するまでにリークされる可能性があります。その後、最後の操作としてdelete this;を呼び出します。

が必要な箇所から中間ステップを追加すると、オブジェクトと削除コード自体を削除する(またはしたい)場合は、操作が複雑で難しくなります。次のコード:

void willDeleteOurself() { 
    delete this; 
    // [1] 
} 

がはるかに明確で読みやすいです:オブジェクトが死んあるので、この時点から、オブジェクトが死んでいる、に、あなたはそれを使用することはできませんが、[1]にコードを追加しないでくださいnow。一方、deleteをコールバックで偽装すると、他の人がコードを見て、[1]にコードを追加することが危険であることに気づかないかもしれません。

+0

はい、あなたが正しいです、直接、 'これを削除します'はより明確です。しかし、私が質問に追加したように、私はこれがスマートなポインタではうまくいかないと思う。 – dada

+0

ここで問題となるのは1つの問題だが、リソースの管理が他の場所で処理されるならば、それがリリースされる場所になければなりません。さもなければ、あなたはリソースの管理を台無しにするでしょう。さて、操作の詳細に応じて、関数の戻り値を使って処理することがわかりました。オブジェクトは*私は今から呼び出し元に無駄です。 –

5

willDeleteYourselfdelete this;を呼び出すのと同じくらい良いです。削除後にメンバーにアクセスしないと問題ありません。

+1

+1: 'これを削除します;'は法律で、多少危険です。 – Puppy

関連する問題