2011-12-21 1 views
2

DerelictとDを使用してSDLチュートリアルシリーズ(C++で書かれています)をフォローしています。チュートリアル作家のスタイルは私を悩まし、私はその周りの最善の方法を理解しようとしてきました。しかし、Dについての私の知識は最善ではないので、私はこれを扱うことが確実ではない。DerelictとSDLでDの外部リソースを管理するための適切かつ明確な方法

基本的にSDLを使用するには、画像ファイルをSDL_Surfacesとしてメモリにロードする必要があります。プログラムが終了する前に、これらのサーフェスをSDL_FreeSurface()を使用して手動で解放する必要があります。これはscope(exit)の理想的なケースのように思えますが、実際にはうまくいきます。単一の機能の範囲内でリソースをロードしたりアンロードしたりするためです。しかし、理想的には、私は1つの関数がロードを処理し、別の関数がそれらを解放するようにすべてを分割します。そして、それを超えて、おそらく各リソースがそれ自身を処理するかもしれません。私はそれがRAIIだと思いますが、私はDでそれを使う方法を本当に理解していません。にロードして~this()でそれを解放しますが、それは私が読んでいるように私はリソースを運ぶために新しいクラスを設定したと思ったクラスをscopeとしてインスタンス化しない限り、デストラクタは呼び出されないことが保証されています。私は推測している構造体を使用することができますが、私がそうした場合、クラスの有用な利点を逃してしまうように思えます。

私が望むのは、リソースを読み込んで解放されることを保証することですが、すべての読み込みと読み込みを1つの巨大なメソッドにする必要はありません。私はこれにどのようにアプローチすべきですか?

答えて

3

少なくとも、マルチタスキングを備えたオペレーティングシステムを搭載したプラットフォームでは、アプリケーション終了時のクリーンアップについて心配する必要はありません。

また、上記のリソースをグローバルセットに格納するだけでもかまいません。

+0

プロセスの外部でリソースを維持できる可能性があります。ビデオカード上、ファイルとして、またはネットワークを介して。 OTOH私はリソースの設計が悪いと思っています。つまり、グローバルなセットは良いアイデアのように聞こえます。 – BCS

+1

+1にCyber​​Shadowが表示します。 @BCS - それは悪い設計ではない、システムは、アプリケーションが終了した後に混乱をクリーンアップすることを保証します。これは非常に強力な保証であり、何百万という開発者がそれに頼っています。 – DejanLekic

+1

私は、スコープ(出口)が機能内に限られていることを(明らかに)上に移動することで、私のジレンマを把握したと思います。だから、メインの "run"関数は、スコープ(exit){clean_up();}を呼び出します。これはおそらくスーパーエレガントではありませんが、クリーンアップを保証する私のケースをすべて網羅しています。 – CodexArcanum

2

SDL_Surfaceを自動的に解放するだけであれば、構造体にSDL_Surfaceをラップし、RAIIを利用するだけです。このタイプのものには適しています。二重の解放を避けるため、または参照カウントを実装するためには、必ずpostblitを無効にしてください。

struct SurfaceRAII 
{ 
    this(SDL_Surface* surf_handle) 
    { 
     m_handle = surf_handle; 
    } 

    // disable default constructor and postblit (no copies) 
    @disable this(); 
    @disable this(this); 

    ~this() 
    { 
     SDL_FreeSurface(m_handle); 
    } 

    public SDL_Surface* m_handle; 
} 

未定ですが、これは一般的な考えです。

編集:もしあなたが好きなら、クラスでstd.typecons.RefCountedを使うこともできます。

+0

自動クリーンアップとは別に、RAIIはスコープ(終了)を超えて何もあなたに与えません。 –

+0

私はpostblitを無効にしたRAII構造体に当てはまると思います。リファレンスカウントされたRAIIオブジェクトは、もっと柔軟性を提供します。 – eco

関連する問題