对于项目,我想隐藏库接口中的一些实现细节。我在处理这种“高效”(在编码和维护方面)的唯一方法是基于相同的抽象基础对抽象和具体基类进行多重继承。所以,是的,我最终得到了一个扩展的钻石结构。
由于它的复杂性,我通常会尽量避免多重继承,所以我在使用它方面不是很有经验,因此我不确定我正在进行的设计是否有一些陷阱我不知道监督。
基本上我需要提供多个“工具”。那些“工具”当然有一些我想用接口ABC隐藏的实现细节,例如:
class Tool1Impl:public ITool1;
class Tool2Impl:public ITool2;
然而,当然这些工具有一些共性。
所以我希望有一个公共基类,但应该通过接口隐藏实现细节。
我想出了以下(钻石)计划:
ITool
/ | \
/ | \
/ | \
ITool1 ToolImplBase ITool2 ... IToolN
\ / \ /
\ / \ /
\ / \ /
ToolImpl1 ToolImpl2 ... IToolImplN
ToolImplBase实现了ITool的纯虚拟功能。 ToolImpl1实现了在ITool1中声明的纯虚函数。
实施大纲如下:
class ITool {
public:
virtual int common_foo(int a) = 0;
};
class ITool1 : public virtual ITool {
public:
virtual int specific_foo(int b) = 0;
};
class ITool2 : public virtual ITool {
public:
virtual int specific_bar(int c) = 0;
};
class ToolImplBase : public virtual ITool {
public:
virtual int common_foo(int a) override;
protected:
int _some_common_data;
};
class ToolImpl1 : public ToolImplBase, public virtual ITool1 {
public:
virtual int specific_foo(int b) override;
private:
int _some_specific_data;
};
class ToolImpl2 : public ToolImplBase, public virtual ITool2 {
public:
virtual int specific_bar(int c) override;
private:
int _some_specific_data;
};
它似乎做了我想要的,但我不确定是否有任何潜在的陷阱或明显的问题。我也不确定我是否可以在继承方案中获得“虚拟”(不是虚拟方法,而是“:public virtual”)。 一个问题是,MSVC(由于此时由于某些外部依赖性,我在2010年遇到困难)给了我编译器警告C4250:
warning C4250: 'ToolImpl1': inherits'ToolImplBase::ToolImplBase::common_foo' via dominance
我可以忽略它吗?我甚至不确定为什么我会得到这个,因为“common_foo”的非主导方式是纯虚拟的,所以实际上没有有效的“非显性”实现。
感谢您的任何输入(“ 从不 使用MI ”除外,我试图尽可能避免使用它。)< / p>
答案 0 :(得分:0)
这里有关于警告的一些解释:What does C4250 VC++ warning mean?
我认为您的代码没有问题,因为您将ITool1设计为界面。
如果您在common_foo
中实施ITool1
功能,则在创建common_foo
时,您将不知道ToolImpl1
的哪个实现会有效。
您会对此问题小心,但其他任何人都可以在common_foo
实施中合法实施IToolX
功能而不会出错。
我的最终评论是:您为什么需要ITool1
来自ITool
? ToolImpl1
已经从ToolImplBase
派生,因此您的实际实现类将始终从ITool
派生。
我会更改IToolX
界面,如下所示
class IToolX{
public:
virtual int specific_foo(int b) = 0;
};