对于一个项目,我想从库接口中隐藏一些实现细节。我想出的处理这种“高效”(在编码和维护方面)的唯一方法是基于同一个抽象基类的抽象和具体基类的多重继承。所以,是的,我最终得到了一个扩展的钻石结构。
我通常会尽量避免多重继承,因为它的复杂性,所以我在使用它方面没有很大的经验,所以我不确定我开始使用的设计是否存在一些我不负责的缺陷。
基本上,我需要提供多个“工具”。这些“工具”当然有一些我希望使用接口ABC隐藏的实现细节,例如:
Tool1Impl类:公共ITool1;
Tool2Impl类:公共ITool2;
然而,这些工具当然也有一些共同点。
因此,我希望有一个公共基类,但是实现细节应该通过接口再次隐藏。
我提出了以下(钻石)计划:
ITool
/ | \
/ | \
/ | \
ITool1 ToolImplBase ITool2 ... IToolN
\ / \ /
\ / \ /
\ / \ /
ToolImpl1 ToolImpl2 ... IToolImplNToolImplBase实现了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虚拟")。一个问题是,MSVC (由于当前的一些外部延迟而陷入了2010年)给了我一个编译器警告C4250:
warning C4250: 'ToolImpl1': inherits'ToolImplBase::ToolImplBase::common_foo' via dominance我能忽略这点吗?我甚至不知道为什么要这样做,因为"common_foo“的非主流方式是纯虚拟的,因此实际上没有有效的”非主导“实现。
感谢您的输入(除了“从不使用M.I”之外,我已经在尽可能避免使用M.I)。
发布于 2016-11-17 10:36:50
这里有一些关于警告的解释:What does C4250 VC++ warning mean?
我认为您的代码没有问题,因为您将ITool1设计为一个接口。
如果您在common_foo中实现了ITool1函数,那么当您创建ToolImpl1时,您将不知道common_foo的哪个实现可以工作。
您将注意这个问题,但是其他任何人都可以合法地在IToolX实现中实现IToolX函数,而不会引发错误。
我最后的评论是:为什么需要从ITool派生您的ITool?ToolImpl1已经从ToolImplBase派生出来了,所以您的实际实现类总是从ITool派生的。
我将更改IToolX接口,如下所示
class IToolX{
public:
virtual int specific_foo(int b) = 0;
};https://stackoverflow.com/questions/40652168
复制相似问题