为什么我的继承接口不使用我的基类覆盖?

时间:2013-06-19 21:35:52

标签: c++ interface multiple-inheritance

我遇到接口和多重继承问题。我希望设计我的程序,以便一个更新调用处理各种对象,每个行为“构建块”隐藏在一个函数中。

例如,我想将一个生物从A点移动到B在一个地方,无论它是否必须执行前/后移动动作。但是,我的多重继承方案失败了(下面,提到了bug),让我觉得我需要在某处复制代码。

显然我对此不太了解! (但我正在努力学习它)

Q1。为什么IPhysics :: Move'在CreatureAirborne类中'看'生物::移动()?

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();
    }
}

2 个答案:

答案 0 :(得分:3)

它有点必须遵循您的层次结构,但它看起来正确评估编译器的部分。

您在任何地方都没有虚拟继承,因此CreatureAirborne从某些角度来看会有重复的基类。您将有两个IPhysics实例。移动,那是抽象的,在生物分支上实现,但在IPhysicsFlight上保持抽象。

您可以通过在某处使用虚拟继承来解决问题,或者通过实现Move in descendant(比如只调用它存在的父版本)来解决问题。

答案 1 :(得分:0)

我会以不同的方式看待事情

class CreatureAirborne : public IPhysicsFlight,Creature

代码运行时

new CreatureAirborne ()

编译器将尝试构建IPhysicsFlight基类和Creature基类,并且IPhysics是基类的事实,两者都不起任何作用而不是混淆。就编译器而言,IPhysicsFlight是抽象的而且CreatureAirborne没有实现移动

当你做

时,钻石问题实际上会发挥作用
(new CreatureAirborne ())->Move()