以下是我在评论中提到的基于虚拟继承的解决方案:
class FirstInterface
{
virtual int getId() const = 0;
};
class SecondInterface
{
virtual void setId(int id) = 0;
};
class CombinedInterface : virtual public FirstInterface,
virtual public SecondInterface
{
};
class FirstConcrete : virtual public FirstInterface
{
virtual int getId() const
{
return 1;
}
};
class CompleteConcrete : virtual public FirstConcrete,
virtual public CombinedInterface
{
virtual void setId(int id) { }
};
void example()
{
CombinedInterface * combinedInterface = new CompleteConcrete();
}
使用虚拟继承时,除了“大象在屋子里”的问题之外,唯一需要的更改是让
CompleteConcrete
从
CombinedInterface
中多重继承,而不是从
SecondInterface
中继承。可以这样考虑:有了
CompleteConcreate
,它现在支持
CombinedInterface
,而不仅仅是增加了
SecondInterface
。
有些人对虚拟继承表示不满,但我不这样认为。虚拟继承是C++的独特功能之一,在我所知的其他高级语言中没有共享。它是一个非常强大的工具,可以解决其他方法难以解决的某些问题。虚拟继承的两个主要缺点是:
因为它非常强大,很容易被滥用,导致各种问题。
如果虚拟继承的类具有非默认构造函数,则很快就会变得棘手,因为现在每个虚拟继承某些东西的类都负责构建它。
但是只要正确使用虚拟继承,并且涉及的类能够构建自己,虚拟继承就是一个有用的工具。
顺便提一下,我还想提供另一种解决方案。如果你的CombinedInterface
只是为了某个特定函数而被引用,比如:
void somefunction(CombinedInterface &object)
你的函数需要一个组合接口。
做出小的更改:
void somefunction(FirstInterface &first, SecondInterface &second)
传递同一对象作为两个参数。可以传递实现两个接口的 CompleteConcrete
,而无需更改类层次结构。您也可以拥有一个模板外观,使其看起来像函数仍然只需要一个参数:
template<typename T> void somefunction(T &&t)
{
real_somefunction(std::forward<T>(t), std::forward<T>(t));
}
void real_somefunction(FirstInterface &first, SecondInterface &second);
你可以基本上摆脱
CombinedInterface
,并且简单地将任何实现这两个接口的对象传递给
somefunction()
,你的
real_somefunction()
将使用其中一个参数来调用适当的接口。假设你需要携带指向同时实现这两个接口的对象的指针?
class combined_pointer : public std::pair<FirstInterface *, SecondInterface *> {
public:
template<typename T> combined_pointer(T *t)
: std::pair<FirstInterface *, SecondInterface *>(t, t)
{}
};
只是一个起点。
CombinedInterface
吗? - Jarod42