いろきゅうの(元)はてなダイアリー

はてなダイアリーから移行中…

罠、大ありorz

1個前の更新ネタで使ったコードですが、結局ワナが待ち構えてました。 orz
ワナのあるコードは次のような感じ。
<罠コード>
typedef __declspec(align(16)) _D3DXMATRIXA16 D3DXMATRIXA;

class C8NumChar // 数字一文字
{
  std::auto_ptr<D3DXMATRIXA> m_psMatrix;
    : // 他色々
};

class C8Score
{
  std::vector<C8NumChar> m_stlNumList;
    : // 他色々
public:
  C8Score(CUINT nKeta) : m_stlNumList(nKeta){}
};
</罠コード>
これだと、vectorが「C8NumCharのコピーコンストラクタが使えない」とエラーを出してきます。何でかよく分らないので、とりあえずC8NumCharにコピーコンストラクタを書いてみました。
ちなみに、C8Scoreでは初期化時にサイズを決定したら、あとはサイズが変わることはありません。よって、どーせコピーコンストラクタなんて使われないだろうと思い、テキトーに書きました。(まぁ、コレがいけなかったんですが…^^;)

class C8NumChar // 数字一文字
{

  std::auto_ptr<D3DXMATRIXA> m_psMatrix;

public:

  // コピーコンストラク
  C8NumChar(const C8NumChar& sr) :
    m_psMatrix(const_cast<C8NumChar&>(sr).m_psMatrix){}

  // 普通のコンストラク
  C8NumChar() :
    m_psMatrix(new D3DXMATRIXA){}
};

これでコンパイルできるようになりました。いざ実行してみると……psMatrixで、ぬるぽが発生しました。 orz

コピーコンストラクタなんて使われてないと思うんだけど…とか思ったら、実は使われていたという罠…。vector(size_type _Count) のコンストラクタでは、1つテンポラリのオブジェクトを生成して、それを各オブジェクトにコピーすることによりオブジェクトを初期化していました…。

結局 vector は何があっても、コピーコンストラクタが正常に働くオブジェクトでしか使っちゃいけないということを学習。
そしてコードは、vectorを使わず、普通に配列を動的確保することにしました。うひー