C++ スタイルのキャスト

C++ のキャストというと static_cast, dynamic_cast, const_cast, reinterpret_cast の 4 種類があります。
C++ の設計と進化(isbn:4797328541)」などを読むと分かるように C++ では
キャストは極力使わないようにしたほうが良いという考えがあるようです。


static_cast は暗黙の型変換で警告が出る場所で使うのが主ですが、
なるべくならばやり取りする変数同士の型をあわせるようにしたほうがいいでしょう。


dynamic_cast は使わなくても良いように設計したほうがプログラムの構造もすっきりします。
また、 dynamic_cast は重い処理なので多用したくないというのもあります。


const_cast はまず使いません。既存の関数の非 const な引数にどうしても
const なオブジェクトを渡す必要があるときに仕方なく使ったりします。
また「Effective C++(isbn:4894714515)」には唯一という正当な使いどころが載っています。


上記の三種のキャストは、なるべくなら使わない方向に持って行きたいキャストです。
しかし reinterpret_cast はちょっと違います。
これはメモリの解釈を変えるキャストで、良くあるのが以下のような処理です。

// 汎用的な、ファイル名を指定してすべてを読み込む処理
void * loadFile(const char * path) {
  FILE * fp = fopen(path);
  fseek(fp, 0, SEEK_END);
  int size = ftell(fp);
  fseek(fp, 0, SEEK_SET);
  void * pBuffer = malloc(size);
  fread(pBuffer, 1, size, fp);
  fclose(fp);
  return pBuffer;
}
BitmapData * pBmpData = reinterpret_cast<BitmapData *>(loadFile("bitmap.bmp"));
PlayerData * pPlyData = reinterpret_cast<PlayerData *>(loadFile("player.dat"));

データがあらかじめ構造体にあわせて配置してあるバイナリファイルを読み込んで
これを任意の型のデータとして取り扱う場合に reinterpret_cast を使用します。


ただし、この方法は基本型のサイズや、構造体のメンバの配置が同じである環境同士でなければ使えません。
int が 2 バイトの環境と 4 バイトの環境では同じファイルを共有できないということです。


最近はとくにコンシューマゲームでもマルチプラットフォームを意識しなければならないため、
互換性が失われる可能性のある reinterpret_cast もやはり使うべきではないのでしょうか。つづく。