我正在尝试使用以下COM接口结构来改进遗留代码:
IBase <- IMammal <- IPet <- ICat
\ \- IDog
\
\- ICattle <- ICow
我无法重新排列或更改此界面,但我想改进实现。我们有几个实现:
CMammal <- CPet <- CCat
\ \- CDog
\
\- CCattle <- CCow
所以,我们有一些常见的哺乳动物实现CMammal :: age(),CMammal :: sex(),一些宠物实现:CPet :: findBed(),CPet :: goThrowughStairs()
还有一些牛/牛实施:CCattle :: goShed(),CCow :: moo()。
问题:我想将age(),sex()实现传播给宠物以及牛,但我不知道该怎么做。
Straighforward解决方案对我来说是不可能的:
class CPet : CMammal, IPet { ... }
因为CMammal和IPet都是从IBase派生的,所以CCat::foo() { IBase::bar(); }
将无法编译,因为IBase不明确。
我设法找到的唯一解决方案是使用模板类进行实现:
template <typename Interface> class CMammal : Interface
{ ... };
template <typename Interface> class CPet : CMammal<Interface >
{ ... };
template <typename Interface> class CCattle : Interface
{ ... };
// "end-point" classes:
class CCat : CPet<ICat> { ... }; // maybe, at least it able to compile
class CDog : CPet<IDog> { ... };
class CCow : CCattle<ICow> { ... };
该解决方案最后可以用C ++实现,但是存在问题:模板类必须在头文件中声明,所以我有很多非常大的头文件,可能编译速度慢,我不知道是什么将以二进制大小发生。
所以,我仍然在寻找一个更好的解决方案,并在此时陷入困境。
有没有想法如何以更清晰有效的方式实现这一点?也许,关于我必须学习的一些想法?
旧的替代方案是这样的几个定义:
#define DECLARE_MAMMAL int sex(); int age();
#define DEFINE_MAMMAL(cls) int cls::sex() { ...; } int cls::age() { ...; }
class CCat : ICat
{
DECLARE_PET
DECLARE_MAMMAL
...
};
// -.cpp-
DEFINE_PET(CCat)
DEFINE_MAMMAL(Cat)
// -.h-
class CCow : ICow
{
DECLARE_CATTLE
DECLARE_MAMMAL
...
};
// -.cpp-
DEFINE_CATTLE(CCow)
DEFINE_MAMMAL(CCow)
此解决方案具有短标题,无复制粘贴,但极难调试。