VC10 と C++0x その5: 続^3・むーぶせまんてぃくす

ねむねむ状態で書いた(言い訳)昨日の記事内容が酷いことになっているので、会社の昼休み中にお勉強し直してみた。
※十分な理解もなしに仕様にケチをつけるとか、色々と恥ずかしいデス……
なんか色々理解があやしいので、かなり初歩的な事からまとめなおしてみる。


昨日の問題点。
そもそも、D3DXVECTOR3 は float 型の実体(xyz)のみを持つ構造体なので、move だろうが copy だろうが効率は変わらない。
ムーブコンストラクタを効果的に使用できる対象(というか、move を使用すべき対象)は、ヒープに領域を確保しているオブジェクトのような、
コピーにコストがかかる移動可能なオブジェクトである
これを、昨日のサンプルクラス hoge を改造する事で再度考えてみる。

class hoge {
public:
    hoge(const D3DXVECTOR3& newFoo)
    {
        foo = new D3DXVECTOR3(newFoo);
    };


    // copy -> コスト大
    hoge(const hoge& newHoge)
    {
        if ( NULL == newHoge.foo ) {
            foo = NULL;
        } else {
            foo = new D3DXVECTOR3(*newHoge.foo);
        }
    };


    // move
    hoge(hoge&& newHoge)
    : foo(std::move(newHoge.foo))
    {};


    // copy operator= -> コスト大
    const hoge& operator=(const hoge& newHoge)
    {
        if ( this == &newHoge ) {
            return *this;
        }
        if ( NULL != foo ) {
            delete foo;
        }
        if ( NULL == newHoge.foo ) {
            foo = NULL;
        } else {
            foo = new D3DXVECTOR3(*newHoge.foo);
        }
        return *this;
    };


    // move operator=
    const hoge& operator=(hoge&& newHoge)
    {
        if ( this == &newHoge ) {
            return *this;
        }
        if ( NULL != foo ) {
            delete foo;
        }
        std::swap(foo, newHoge.foo);
    };


private:
    D3DXVECTOR3* foo;
};

たぶんあってる(関連する処理以外は意図的に書いてないよ)。
この例だとデータサイズが小さいから恩恵はそこまででもないけど、データのでかくなる stl の string や コンテナに対しては move は絶大な効果を発揮する。


と、ここまでが move を使用する基本的なシチュエーションのおさらい。
んで、ようやく昨日書いた、move に対応していない構造体やクラスを自前でラッピングしなきゃいけない話に戻る訳だけど、
DirectX の場合だと IDirect3DTexture9 なんかの move 時とかは、自前で書いてやる必要がある(ような気がする)。
ただ、IDirect3DTexture9 を move するのかと言われると激しく微妙(スマポ + com 管理のクラスを自前で用意するのが普通)なので、
結局自前クラスと stl 絡みの時に使えば良いだけなのかも……。
何にせよ実装経験値が足りないので、勉強しながらもりもり使っていく方向で頑張ろう。