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

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

クラス関係に悩む

ゲームの話で、仮に

機体A〜Hの8タイプがある。描画するとき、機体Hについては特別な描画を用いるが、他の機体は同じアルゴリズムを利用する。

という時、どう実装するべきか、毎回ちと惑う。ちなみに Draw は CCharBase から呼ばれる事前提です。

候補1

機体基底クラスでDrawを実装し、派生クラスはオーバーライドしたけりゃしてくれ方式。


// すべてのキャラクター基底クラス
class CCharBase
{
public:
    virtual int Draw() = 0;
};

// 機体基底クラス
class CPlane :
    public CCharBase
{
public:
    virtual int Draw(){ ごにょごにょ; };
};

// 機体個別
// Draw は実装しない
class CPlaneA :
    public CPlane
{
public:
};

class CPlaneB{};    // + CPlaneA と同く Draw を実装しない。
class CPlaneG{};    // |

// H は特別
class CPlaneH :
    public CPlane
{
public:
    int Draw();
};

候補2

機体基底クラスは、インターフェースっぽく扱うけど、共通関数を持って派生先から呼ぶことにしようゼ方式。


// すべてのキャラクター基底クラス
class CCharBase
{
public:
    virtual int Draw() = 0;
};

// 機体基底クラス
class CPlane :
    public CCharBase
{
public:
    virtual int Draw() = 0;
protected:

    int DefDraw();
};

// 機体個別
class CPlaneA :
    public CPlane
{
public:
    int Draw(){ return DefDraw(); }
};

class CPlaneB{};    // + Draw の実装は CPlaneA と同じ
class CPlaneG{};    // |


// H は特別
class CPlaneH :
    public CPlane
{
public:
    int Draw();
};

候補1だと、CCharBase から Drawが呼ばれた時、どこまで子にさかのぼるべきなのか判らない。CPlaneに実装あるけど、派生先でオーバーライドされてたらそっち呼ばれちゃうので混乱しね? って点から、私は候補2の 「実装はもっとも子で」 方式を採用してるのです。
が……これはコレで、派生先すべてで関数を実装しなきゃならんのでメンドウじゃね? と思ってみるわけで…(ぉ ^^;

難しいなぁー。