我想通过提供一组纯抽象类来为我编写的库提供稳定的API。
考虑以下类层次结构:
//Note: Destructors left out for readability
struct IBase{
virtual void something() = 0;
}
struct IDerivedA : public IBase{
virtual void another() = 0;
}
struct IDerivedB : public IBase{
virtual void another(int a) = 0;
}
这些接口将有多种实现方式。要编写实现,我会这样做:
struct Base : public IBase{
int x; //x is required to implement something()
virtual void something();
}
struct DerivedA : public IDerivedA, public Base{
virtual void another();
}
struct DerivedB : public IDerivedB, public Base{
virtual void another(int a);
}
这导致了可怕的钻石问题,我看到了以下解决方案:
IBase
和IDerivedA
中实际上继承IDerivedB
,只使用多重继承Base
,而是将调用转发给帮助程序类以避免代码重复类似的东西:
struct Base{
int x; //x is required to implement somethingImpl()
void somethingImpl();
}
struct DerivedA : public IDerivedA{
virtual void something(){ b.somethingImpl(); };
virtual void another();
private:
Base b;
}
struct DerivedB : public IDerivedB{
virtual void something(){ b.somethingImpl(); };
virtual void another(int a);
private:
Base b;
}
在1)的情况下,每次在API层中使用继承时都需要虚拟继承。
在2)的情况下,我需要为每个实现类包装Base
,这会导致代码膨胀。
我认为设计中可能存在根本性的错误。这个具体案例是否有一般的最佳做法?