3

インターフェイスと多重継承に問題があります。1 回の update 呼び出しでさまざまなオブジェクトを処理し、それぞれの動作の「ビルディング ブロック」を 1 つの関数に収めるようにプログラムを設計したいと考えています。

たとえば、移動前/移動後のアクションを実行する必要があるかどうかに関係なく、クリーチャーをポイント A から B に 1 か所で移動したいと考えています。しかし、私の多重継承スキームは失敗し (以下、バグが修正されました)、コードをどこかに複製する必要があると思います。

明らかに、私はこれを十分に理解していません!(でも勉強頑張ってます)

Q1. CreatureAirborne クラスで IPhysics::Move が Creature::Move() を「参照」できないのはなぜですか?

Q2. インターフェイスや多重継承の適切な使用法を完全に見逃していますか? もしそうなら、どんな指導も大歓迎です!

#include <deque>
#include <memory>

class IGameObject
{
public:
    virtual ~IGameObject() {}

    virtual void Update() = 0;
};

class IPhysics
{
public:
    virtual ~IPhysics() {}

    virtual void Move() = 0;
};

class IPhysicsFlight : public IPhysics
{
public:
    virtual ~IPhysicsFlight() {}

    virtual void Land() = 0;
    virtual void TakeOff() = 0;
};

class Creature : public IGameObject, IPhysics
{
protected:
    virtual void Move() {}

public:
    Creature() {}
    virtual ~Creature() {}

    virtual void Update() {}
};


class CreatureAirborne : public Creature, IPhysicsFlight
{
private:
    virtual void Land() {}
    virtual void TakeOff() {}

public:
    CreatureAirborne() {}
    virtual ~CreatureAirborne() {}

    virtual void Update();
};

void CreatureAirborne::Update()
{
    TakeOff();

    Creature::Move();

    Land();
}

int main()
{
    std::deque<std::shared_ptr<Creature>> creatures;

    std::shared_ptr<Creature> cow(new Creature);

    creatures.push_back(cow);

// The butterfly fails to compile with 'cannot instantiate; void IPhysics::Move(void) is abstract'

//  std::shared_ptr<CreatureAirborne> butterfly(new CreatureAirborne);

//  creatures.push_back(butterfly);

    for (auto i : creatures)
    {
        i->Update();
    }
}
4

2 に答える 2

3

階層に従う必要がありましたが、コンパイラ側では正しい評価に見えます。

どこにも仮想継承がないためCreatureAirborne、ある時点から基本クラスが複製されます。IPhysics の 2 つのインスタンスがあります。ムーブは、Creature ブランチで実装されていますが、IPhysicsFlight では抽象的なままです。

どこかで仮想継承を使用するか、子孫に Move を実装することで状況を解決できます (たとえば、存在する親バージョンを呼び出すだけです)。

于 2013-06-19T21:53:25.243 に答える