假设我有一个很大的类层次结构作为一棵单独的根树,根是class A
,因此它的每个后代都有自己的void f(...)
和void g(...)
实现,并带有不同的参数列表。
我还有另一个类class X: public A
,在其某些方法中仅使用基类f(...)
和g(...)
。现在,我想将X
中的方法扩展到A
的所有子类型:假设A
的子类型为B
,新类为class BX
。要求是:
class BX
应该使用f(...)
中的g(...)
和class B
,以及class X
中的所有方法。class BX
应该遵守class A
的界面。我想出的解决方案是使用template<typename B> class BX: public B
来避免1中出现钻石问题。
有没有更好的方法来实现我想要的?
答案 0 :(得分:0)
根据我的经验,如果您仅继承接口(仅虚拟)并使用合成和委托来共享实现,那么继承的许多问题就会消失,但是奇怪的是重复使用的模板模式或CRTP,这就是您在这里使用的是解决此问题的另一种常用方法。
答案 1 :(得分:0)
template<class D>
struct X {
A* self(){ return static_cast<D*>(this); }
A const* self() const{ return static_cast<D*>(this); }
void foo(){
self()->f( 1, 2, 3 );
}
};
struct XA: A, X<XA> {};
struct XB: B, X<XB> {};
在X<XB>
(实施XB
的范围内,您只能访问A
。
如果您希望用户仅看到A
,则仅将XB
公开为A
。
请注意,这可能毫无用处,因为访问XB
/ X<XB>
中的任何更改都需要知道您的对象不是A
,因为X<XB>
不会被修改A
界面中的任何内容。