smart_ptr_base




smart_ptr(スマートポイント)は、yaneSDK3rdではディフォルトで所有権を持つように変更しました。すなわち、

list-1
    smart_ptr<IHoge>    p(new CHoge);


のようにすれば、pは所有権を持ちます。すなわちpの解体フェイズにおいて、このオブジェクトはdeleteされます。所有権を持たせたくないときは、

list-2
    smart_ptr<IHoge>    p(new CHoge,false);


のように書きます。この点、yaneSDK2ndと異なるので注意してください。

スマートポインタの概念的な説明については、yaneSDK2ndのときからあるので、ここで詳しく書く必要は無いでしょう。(「天才ゲームプログラマ養成ギプス」も参考にしてください)

3rdのsmart_ptrには、配列をポリモーフィックに扱う機構が備わっていますが、そのへんの実装については「やね本1」のほうでも詳説していますし、クラスヘッダに説明が書いてありますので、そちらも参考にしてください。

前の章で出てきた、CThreadManager、案外作るのに苦労したシロモノでして、たとえば大きく次の2つの問題点があります。

1.すべてのスレッドを停止させている途中に、新しいスレッドが生成されたとき、どうなるのか?(正しく解体されるのか?)

2.CThreadManagerが自分が所有権を持っているスレッドを停止を見て、そのスレッドオブジェクトを解体したいのが、そのスレッドオブジェクトは、スレッド派生クラスとは限らず、スレッドをコンポジションによって構成しているかも知れない。

枠-1
例)
    class CApp {
        CThread thread_;
    };


CApp::thread_のスレッド停止時に、CAppのオブジェクト(これは、事前に型のわからないオブジェクト)を解体するというようなアクロバット的なことは可能なのでしょうか?
これは、可能です。handle-bodyのイデオムを応用して、smart_ptrで次のようなことが出来ます。

1.まず、smart_ptrをnewします。

枠-2
    smart_ptr<CApp>* p = new smart_ptr<CApp>(pApp);


2.そのポインタをsmart_ptr_base*に代入します。

枠-3
    smart_ptr_base* q = p;


smart_ptr_baseとは、すべてのsmart_ptrの基底クラスです。smart_ptrはテンプレートですが、smart_ptr_baseという共通の基底クラスを持っています。

3.オブジェクト(body)を削除したいときは、smart_ptr_baseを通じてdeleteします。

枠-4
    delete q;


もちろん、1.2.の手順は、直接

枠-5
    smart_ptr_base* q = new smart_ptr<CApp>(pApp);

と書いてかまいません。

1.〜3.によって、あらゆるオブジェクトを、smart_ptr_baseというドラえもんのポッケに閉じ込め、好きなときにdeleteすることが出来るというわけです。さきほどのスレッド停止時に、そのスレッドと関連するオブジェクトを削除するというのは、この機構によって実現できます。(実現しています)