MENU閉じる

HEXA BLOG

プログラム

HEXA BLOGプログラム2010.4.9

using

こんにちは、イワムーですわーい(嬉しい顔)
スギ花粉が終息し、ホッと一息ついていたのもつかの間、次はヒノキ花粉が猛威を奮っていますねたらーっ(汗)
以前に無花粉スギの開発に成功したというニュースを見て大喜びした覚えがありますが、無花粉ヒノキの開発も切に願ってやみません・・・。(もうあるかもexclamation&question

さて、今日はC++プログラムの小ネタを紹介しようと思いますひらめき
継承ポリモーフィズムの話です。
(分からない方は詳しく解説された他のWebページがあるので、そちらを参照してください)
class CharacterBase {
public:
  CharacterBase(void){}
  ~CharacterBase(void){}
  //初期化処理
  virtual void init(const Vector& position, const Vector& direction);
private:
  // メンバ定義
};
class Player : public CharacterBase {
public:
   Player (void){}
   ~Player (void){}
   //初期化処理
   void init(const Vector& position, const Vector& direction, const Vector3& scale);
private:
   // メンバ定義
};
上記例では、ポリモーフィズムの概念上、コンパイラは警告を出しますふらふら
警告が出る・出ないはコンパイラ、またコンパイラの警告レベルに依存します
initという名前のメソッドは基底クラスの仮想関数になっています。
今回のケースでは、派生クラスで同名のメソッドを宣言しているため、コンパイラ側からは「基底の仮想関数をオーバーライドするつもりで、引数を間違えたのではないか?」と見えてしまいます。
ですが、コーダーの意図としては「基底側と同様に機能としては初期化処理なのでinit()という名前のメソッドにしているが、引数や戻り値の異なる、基底側のinit()とは別のメソッドとして定義した」わけなので、コンパイラにその意図を知らせてあげればよいわけです。
class Player : public CharacterBase {
public:
   Player (void){}
   ~Player (void){}
   //初期化処理
   using CharacterBase::init; // ※この宣言に注目!!
   void init(const Vector& position, const Vector& direction, const Vector3& scale);
private:
   // メンバ定義
};
ここで using の登場ですexclamation×2
このように基底クラスの同名メソッドをusing宣言しておくことで、警告を回避できるわけですグッド(上向き矢印)
using は名前空間を使用する際によく用いられる機能ですが、上記ケースでの利用はあまり知られていない(?)かと思ったので、紹介させていただきましたわーい(嬉しい顔)
何かのお役に立てばと思いますexclamation
補足:
上記例では、コンパイラの警告を除外することでも回避できます。
もちろん init()でなく、initPlayer()のようにメソッド名を変えるだけでも解決できます。
基底クラスと派生クラスで初期化処理を分けなければいけないような設計自体を見直すことも考えるべきかもしれません。
このあたりはケースバイケースですねー(長音記号2)

RECRUIT

大阪・東京共にスタッフを募集しています。
特にキャリア採用のプログラマー・アーティストに興味がある方は下のボタンをクリックしてください

RECRUIT SITE