在父类

时间:2017-02-06 04:36:22

标签: c++ oop c++11 multiple-inheritance

我有一个独特的案例,我需要两层接口,并希望有两层类来实现它们:

class IFood {
public:
    virtual ~IFood() = default;
    virtual int GetColor() const = 0;
};

class IFruit : public IFood {
public:
    virtual int GetAverageSeedCount() const = 0;
};

class GreenFood : public IFood {
    virtual int GetColor() const override {return GREEN;}
};

class GreenApple : public GreenFood, public IFruit {
    virtual int GetAverageSeedCount() const override {return 5;}
};

(我意识到这些界面并不完美。抱歉。)

在某些情况下,我可能有一个IFood对象的集合,但在其他情况下,我将有一个IFruit对象的集合。实际上,IFood代表的界面有5-8个功能。

如果这段代码编译并运行,我将被设置。不幸的是,它失败了,因为编译器没有意识到GreenApple实现了IFood API(缺少GetColor)。这确实存在于我们扩展的基类GreenFood中,但拆分接口实现似乎并没有使编译器满意。

对于IFood中的每个函数,我可以让IFruit实现它并直接调用ParentClass :: functionName()。但是在IFood中有5-8种功能和几十种潜在的水果类型,这并不像我想的那么优雅。

我很好奇是否有任何解决方案让编译器在父类中找到这些缺失的API,或者我有什么好的方法来重构我的接口以保持优雅?

如果需要,我可以提供更具体的例子。感谢您的任何提示!

2 个答案:

答案 0 :(得分:2)

在IFruit和GreenFood中为基类使用Virtual关键字。

class IFood {
public:
    virtual ~IFood() = default;
    virtual int GetColor() const = 0;
};

class IFruit : public virtual IFood {
public:
    virtual int GetAverageSeedCount() const = 0;
};

class GreenFood : public virtual  IFood {
    virtual int GetColor() const override {return GREEN;}
};

class GreenApple : public GreenFood, public IFruit {
    virtual int GetAverageSeedCount() const override {return 5;}
};

答案 1 :(得分:-1)

有几种方法可以解决这个问题。

首先,GreenApple知道它继承自GreenFoodIFruitIFruit继承了自己要求GetColor()的要求,这是在GreenFood()中实现的,所以从一个角度来看,GreenApple有责任照顾这个:

class GreenApple : public GreenFood, public IFruit {
    virtual int GetAverageSeedCount() const override {return 5;}
    virtual int getColor() const override {
         return GreenFood::GetColor();
    }
};

稍微清晰一点的变化,避免了丑陋的显式类引用:

class GreenFood : public IFood {
    virtual int GetColor() const override
    {
         return GreenFoodColor();
    }

    int GreenFoodColor() const
    {
           return GREEN;
    }
};

class GreenApple : public GreenFood, public IFruit {
    virtual int GetAverageSeedCount() const override {return 5;}
    virtual int getColor() const override {
         return GreenFoodColor();
    }
};

这可以工作,但这仍然会导致GreenApple继承IFood两次。这可能会产生自己的问题。

避免重复继承的替代解决方案是直接从IFruit继承IFood,而是要求其子类以某种方式从该接口继承:

class IFruit {
public:
    virtual int GetAverageSeedCount() const = 0;

    virtual IFood &getIFood()=0;

    virtual const IFood &getIFood() const=0;
};

class GreenApple : public GreenFood, public IFruit {
    virtual int GetAverageSeedCount() const override {return 5;}

    virtual IFood &getIFood() override { return *this; }

    virtual const IFood &getIFood() const { return *this; }
};

任何查看IFruit的内容都知道IFood隐藏在这附近的某个地方。也许在那里推operator IFood &,使整个过程更加透明。