質問

私は過去4年間にC#でに興味がある私にとって現在のベストプラクティスを共通デザインパターンC++.考え、以下の一部の例:

class World
{
public:
    void Add(Object *object);
    void Remove(Object *object);
    void Update();
}

class Fire : Object
{
public:
    virtual void Update()
    {
        if(age > burnTime)
        {
            world.Remove(this);
            delete this;
        }
    }
}

この世界を担う管理するためのオブジェクトを更新します。火災はオブジェクトがあり、世界の多くの異なる状況が一般的に他のオブジェクトです。火災のオブジェクトを知っている場合に焼き尽くされたので現在までの削除そのものです。のオブジェクトを作成した、火災がなくなり存在しくは関係します。

この良識あるいはあるようにデザクリーンアップするための支援これらのオブジェクト?

役に立ちましたか?

解決

これに伴う問題は、あなたが本当にオブジェクトと世界クラスの間の暗黙的な結合を作成しているということです。

私は何が起こる、ワールドクラスの外側更新()を呼び出すしようとすると?私は、オブジェクトが削除された状態で終わるかもしれない、と私は理由を知りません。責任がひどくアップ混在しているようです。これは、問題、あなたがこのコードを書いたときを考えていなかった新しい状況で火災クラスを使用した瞬間を引き起こすことが起こっています。オブジェクトが複数の場所から削除する必要がある場合はどうなりますか?おそらくそれは世界から、現在のマップ、およびプレイヤーのインベントリの両方を削除する必要がありますか?あなたの更新機能が悪いことが起こる、世界からそれを削除して、オブジェクトを削除し、次回は、マップやインベントリがオブジェクトにアクセスしようとします。

一般的に、私はそれはそれは、更新されたオブジェクトを削除するには、Update()関数のための非常に直感的であると思います。私もそれ自体を削除するオブジェクトのための直感的だと思います。 目的は、より可能性が高いそれは燃えて終了し、興味がある人々は今その上で行動することを言ってイベントを発生させる方法のいくつかの種類を持っている必要があります。世界からそれを除去することにより、例えば。それを削除するために、所有権の観点から考える。

オブジェクトを所有している誰ですか?世界?それだけで世界はオブジェクトが死ぬ時に決めることを得ることを意味します。それは限り、オブジェクトへの世界の参照がそれに他の参照を長持ちしようとしているとして、罰金です。 あなたは、オブジェクト自体を所有していると思いますか?それは一体何の意味ですか?オブジェクトはもう存在しないときに、オブジェクトが削除されるべきではありませんか?意味をなさないます。

しかし、明確に定義された単一の所有者は何がある場合、そのようなboost::shared_ptr

のように、参照カウントを実装するスマートポインタを使用して、例えば、共有所有権を実装していません

しかしか否か、それが存在し、そしてそれはまた、他のリストに存在するか否かを、 1 の特定のリストからオブジェクトを除去するためにハードコードされているオブジェクト自体、上メンバ関数を有します、ともかかわらず、それへの参照が存在するのオブジェクト自体を削除し、悪い考えです。

他のヒント

あなたは、派生クラスがUpdateの実装を無効にすることができることを示唆し、Update仮想関数を作ってきました。これは、二つの大きなリスクを紹介します。

1。)オーバーライドされた実装がWorld.Removeを行うことを覚えているかもしれませんが、delete thisを忘れることがあります。メモリがリークします。

2)オーバーライド実装ではなく、無効なこのポインタと、Updateを行うベースクラスdelete thisを呼び出し、その後より多くの仕事と進む。

この例を考えてみます:

class WizardsFire: public Fire
{
public:
    virtual void Update()
    {
        Fire::Update();  // May delete the this-object!
        RegenerateMana(this.ManaCost); // this is now invaild!  GPF!
    }
}
オブジェクトは、参照カウントのほとんどの実装は、同様のものを使用しますC ++で自分自身を削除すると、実際には何も問題はありません。しかし、それは少し難解な技術として上を見ていると、あなたが所有権の問題に本当に近い目を維持する必要があります。

、削除は失敗し、オブジェクトは、のないの割り当てられ、newで構築した場合、プログラムをクラッシュすることがあります。この構築物は、スタックまたは静的クラスをインスタンス化を防止することができます。あなたのケースでは、割り当て方式のいくつかの種類を使用しているように見えます。あなたはそれに固執するならば、これは安全かもしれません。私は確かにかかわらず、それをしないでしょう。

私は厳しい所有権のモデルを好みます。世界はそれ内のオブジェクトを所有し、それらをクリーンアップするための責任を負わなければなりません。どちらのは、世界がそれを行う削除または更新(または別の関数)を持っているオブジェクトが削除されるべきであることを示す値を返す必要があります。

私はまた、この種のパターンでは、あなたはダングリングポインタで終わるを避けるために、あなたのオブジェクトを参照カウントしたいしようとしていることを推測しています。

それは確かに作品のために作成したオブジェクト new ときに呼び出し側の Update は正しい知識と行動です。もう動きが出始めている。このケースでは、有明の世界は、世界を削除します。のオブジェクトを生じさせるものではありませんそのものだと思いるものでなければならないのかな削除は行いません。できる非常に驚きにお問い合わせいただいた場合の機能を"更新"がオブジェクトが、そこに突然そのオブジェクトは、既存のもうなく世界の何ものそのもの以外のものを取り除いていただいても、リストが別のフレーム!のコードを呼び出しのオブジェクトは通知いします。

自分のこ

  1. 追加のリストオブジェクトへの参照です。各オブジェクトがリスト待ち状態の除去.この共通の手法で使用されていwxWidgetsのための典windows休館していたが、まだメールを受信する.アイドル時に、すべてのメッセージが処理され、保留のリストを処理し、オブジェが削除されます。と思いQt以下同様。
  2. 世界を教えてくれるオブジェクトのために削除されます。世界で適切に通知を行うの他のものと必要とされている。ようなもの deleteObject(Object&) も参考になり嬉しいです。
  3. を追加 shouldBeDeleted 機能と各オブジェクトがtrueを返す場合、オブジェクトを願によって削除されることがあります。

いうオプション3.世界の呼びます。そして、本プロジェクトの完成ですか、オブジェクトは削除され、いただいて覚えることにより追加するオブジェクトへの保留中の除去リストになります。

この痛みは、お尻ができない場合はアクセスできる機能やデータのオブジェクトです。例えば、wxWidgetsあwxThreadクラスで運用できます。モードになり、これらのモード(着脱式)の場合は、その主な機能を返します(そのスレッドのリソースにすべきで削除し、そのメモリを解放してください占めにwxThreadオブジェクト)を待つのではなく、オーナーのスレッド呼び出すオブジェクトを待ちまたは参加。しかし、これにより厳しい頭痛がしてきた。できない他の機能までになりますので注意してください終了させような状況の下できませんのでご了承くださいすることができない。かなりあっても嫌いになる挙動をします。

自己の削除参照対象のオブジェクトが香り,まぁ.う:

// bitmap owns the data. Bitmap keeps a pointer to BitmapData, which
// is shared by multiple Bitmap instances. 
class Bitmap {
    ~Bitmap() {
        if(bmp->dec_refcount() == 0) {
            // count drops to zero => remove 
            // ref-counted object. 
            delete bmp;
        }
    }
    BitmapData *bmp;
};

class BitmapData {
    int dec_refcount();
    int inc_refcount();

};

を比較する自己の削除refcountedオブジェクト

class Bitmap {
    ~Bitmap() {
        bmp->dec_refcount();
    }
    BitmapData *bmp;
};

class BitmapData {
    int dec_refcount() {
        int newCount = --count;
        if(newCount == 0) {
            delete this;
        }
        return newCount;
    }
    int inc_refcount();
};

と思うので楽しむことができると思いられる設計の参考計数オブジェな ない do"削除"で増結:のクラスの参照対象のデータでは、知覚えていて、データを削除してcreateactionpropertychangelistener decrementingの参考数です。注どのように"bmp"となりの可能性のぶポイン~ビットマップのデストラクタ.ューになる"削除"は素晴らしいです。

答えは類似の問題 "何の使用を削除すること"

これはかなり一般的な参照カウントの実装だと私はそれ以前に正常に使用しました。

しかし、私はまた、それがクラッシュ見てきました。私はクラッシュのための状況を覚えていることがしたいです。 @abelenky には、それがクラッシュし、私が見てきた一つの場所です。

これはどこさらにサブクラスFireあったが、(下記参照)仮想デストラクタの作成に失敗した可能性があります。あなたは仮想デストラクタを持っていない場合は、Update()機能は、適切なデストラクタ~Fire()の代わりに~Flame()呼び出します。

class Fire : Object
{
public:
    virtual void Update()
    {
        if(age > burnTime)
        {
            world.Remove(this);
            delete this; //Make sure this is a virtual destructor.
        }
    }
};

class Flame: public Fire
{
private: 
    int somevariable;
};

その他の問題に言及している「これを削除します。」 「世界は」火の作成を管理するので要するに、それはまた、その削除を管理する必要があります。

世界はまだ燃えて火で終了した場合、

もう一つの問題があります。これは火が破壊することができる、それを通して唯一のメカニズムである場合は、孤児やごみの火で終わる可能性があります。

は、あなたが欲しいのセマンティクスのために、私はあなたの「火」クラスの「アクティブ」または「生きている」フラグを持っているでしょう(または該当する場合オブジェクト)。そして、世界は機会に、オブジェクトのその在庫を確認し、アクティブでないものを取り除くでしょう。

-

もう一つのノートには、それはそれはあまり一般公衆inheiritanceよりであっても、デフォルトであるため、書かれたコードが、火は個人Objectから継承していることです。おそらく、継承の種類を明示すべきである、と私はあなたが本当に公共inheritianceをしたいと思う。

これは、一般的にしない限り、必要に応じて、または非常に単純な方法で使用される「これを削除」を行うには良い考えではありません。あなたのケースでは、それが取り除かれたとき、我々は(彼らは通知されませんので、その場合には、お使いの削除呼び出しはエラーになります)を見ていない他の依存関係が存在しない限り、世界はただ、オブジェクトを削除することができますように見えます。あなたのオブジェクトの外に所有権を維持することは、あなたのオブジェクトは、より良いカプセル化され、より安定にすることができます:それは自分自身を削除することにしたというだけの理由オブジェクトには、いくつかの点で無効になることはありません。

私はしないで、この存在自体を削除するオブジェクトと、本質的に何か問題がありますが、別の可能な方法は、世界がの::削除一環としてオブジェクトを削除する責任を持っているだろう(全て削除されたオブジェクトも削除されたと仮定。)

これは非常に危険です削除します。それに「間違っている」ものは何もありません。それは法的です。しかし、あなたは、それは慎重に使用する必要があること、それを使用するときに間違って行くことができますので、多くのものがあります。

誰かがオブジェクトにオープンポインタまたは参照を持っており、それが行くと自分自身を削除する場合を考えてみましょう。

ほとんどの場合、私は、オブジェクトの有効期間は、それを作成し、同じオブジェクトによって管理されるべきだと思います。それだけで破壊が発生する場所、それが簡単に知ることができる。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top