在父 class 中实现部分 C++ 接口

Implementing partial C++ Interface in parent class

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

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 个函数和几十种潜在的水果类型,这并不像我想要的那样优雅。

我很好奇是否有任何解决方案可以让编译器在父 class 中找到这些丢失的 API,或者有什么好的方法可以让我重组我的接口以保留东西优雅?

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

在 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;}
};

有几种解决方法。

首先,GreenApple知道它同时继承了GreenFoodIFruit,而IFruit继承了自己对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 参考:

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

这会起作用,但这仍然会导致 GreenAppleIFood 继承两次。这可能会产生自己的问题。

另一种避免重复继承的解决方案是不让 IFruit 直接继承自 IFood,而是要求其子 class 从该接口继承,在某些情况下方式:

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 &,使整个过程更加透明。