Decremented Blog

プログラミング、釣り、工作など、ジャンルを特に定めず、適当に書かれたブログです。

[C++] 配列テンプレート使用時の注意点

2009-02-02 22:32:16 | プログラミング・開発
ATLやSTL等のC++テンプレートライブラリでは、クラスの配列型を実現するためのテンプレートが用意されています。
ATLではCAtlArray等、STLではvector等です。

これ、非常に便利なのですが、動作をちゃんと理解していないと、予想外の動作をしたりします。
例えば、下記のようなクラスは、そのままでは配列型にできません。
class CTest { CTest() { // バッファのポインタを設定 m_ptr = m_buf; } // ポインタを取得する char *GetPtr() { rerurn m_ptr; } // ポインタ char *m_ptr; // バッファ cahr m_buf[10]; }

GetPtr()で、m_ptrを経由してm_bufのポインタを取得できるはずですが、クラスを配列型のテンプレートに入れていると、要素の挿入や削除を行ったタイミングでm_ptrがm_bufを指さなくなり、取得できなくなります。

テンプレートの標準の実装では、高速化のために、memmove等を使ってクラスのメモリ領域を移動するよう作られている為です。
つまり、m_bufの位置は移動しますが、m_ptrの内容はそのままコピーされるため、矛盾が発生してしまいます。

このような場合は、テンプレートの移動メソッドをオーバーライドして独自の移動メソッドを実装することで解決できます。(ちなみに、MFCのCArrayはできません)
また、普通の配列テンプレートでは、コンストラクタに引数を持つことはできません。
ただ、これは構造上不可能な訳ではないため、自分で配列テンプレートを作れば可能です。
まあ、余り使わないかもしれませんが・・・