在父 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
知道它同时继承了GreenFood
和IFruit
,而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();
}
};
这会起作用,但这仍然会导致 GreenApple
从 IFood
继承两次。这可能会产生自己的问题。
另一种避免重复继承的解决方案是不让 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 &
,使整个过程更加透明。
我有一个独特的案例,我需要两层接口,并希望有两层 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
知道它同时继承了GreenFood
和IFruit
,而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();
}
};
这会起作用,但这仍然会导致 GreenApple
从 IFood
继承两次。这可能会产生自己的问题。
另一种避免重复继承的解决方案是不让 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 &
,使整个过程更加透明。