5

私は現在、C ++でゲームに取り組んでいます。ガベージ コレクターがないため、オブジェクトを常に慎重に削除し、削除されたオブジェクトがアクセスされないようにする必要があります。
プロジェクトが成長するにつれて、いくつかのオブジェクトがますます多くの場所から参照されるようになります。たとえば、ゲーム内のユニットは、レンダラー、シーン階層、選択メカニズム、HUD などから参照される場合があります。現在 - オブジェクトが削除された場合、このオブジェクトを参照する他のすべてのクラスに通知されるようにする必要があります。
または、逆に言えば、ユニットの1つを参照する可能性のある新しいクラスを作成する場合、ユニットのコード(またはユニットマネージャーまたはユニットを削除するモジュールのコード)も変更する必要があります。この新しいモジュールが、現在参照している特定のユニットがいつ削除されるかを確実に認識できるようにします。

今、私は、別のオブジェクトがサブスクライブできるベースクラスを作成することにより、この問題を解決するための単純なイベント駆動型の汎用アプローチがあると考えています。このようなもの:

class DeletableBase;//forward declaration

class ISubscriber{
public:
    virtual someObjectGotDeleted(DeletableBase* deletedObject)=0;
};

class DeletableBase{
private:
    vector<ISubscriber*> subscribers;
public:
    virtual ~DeletableBase(){
        for(int i=0; i<subscribers.size(); i++)
            subscribers[i]->someObjectGotDeleted(this);
    }
    subscribeForDeleteEvent(ISubscriber* subscriber){
        subscribers.push_back(subscriber);
    }
};

それで、新しいクラスからこのクラスを継承するオブジェクトを参照する場合、自分自身をサブスクライバーとして追加するだけで、オブジェクトが他の場所から削除される場合、それについて通知されます。

これは「クリーンな」コーディング方法ですか?

4

4 に答える 4

6

これが (状態の変更ではなく) 純粋にメモリ管理に関するものである場合は、代わりにスマート ポインターを使用してください。から始めて、 /shared_ptrを使用して最適化するか、遅すぎる場合は最適化します。make_sharedallocate_sharedboost::intrusive_ptr

于 2011-02-02T14:53:24.967 に答える
1

考慮しなければならないことの 1 つ (特にゲームを作成している場合) は、サブスクライブしているオブジェクトの 1 つがメイン スレッドで削除されると、各サブスクライバーが何をしようとしても完了するまでゲームがブロックされる可能性が高いということです。オブジェクトの削除時に行うこと。注意しないと、ゲームのパフォーマンスに影響を与える可能性があります。

于 2011-02-02T14:53:46.680 に答える
0

IMHO、独自のメモリ アロケータを実装する必要があります。各インスタンスを観察する代わりに、インスタンス タイプまたはクラスに関して解放されたメモリを観察することができます。もちろん、そのためには、メモリ アロケータを監視可能にする必要があります。より効果的にオブザーバーに通知するために、データ構造またはそれらのバージョンを使用mapまたは好むことができます。つまり、メモリ マネージャーはメディエーターであり、観察可能でもあります。setmulti

さらに、これらの解放アクションまたは通知アクションが互いに独立している場合は、コマンド パターンを使用して実行コンテキストとスレッド コンテキストを分離できます。お役に立てれば。

于 2011-02-02T15:27:25.227 に答える
0

他のオブジェクトによって参照されるオブジェクトを削除することは避けなければなりませんが、その逆は避けなければなりません。Boost スマート ポインターは、作業の 90% を行います。

PS: C++ 用のガベージ コレクターがあります :-)

于 2011-02-02T15:04:56.783 に答える