如何重构类层次结构以避免菱形问题
How to refactor class hierarchies to avoid diamond problem?
假设我有一个作为单根树的大型类层次结构,根为class A
,因此它的每个子代都有自己的void f(...)
和void g(...)
实现,具有不同的参数列表。
我有另一个类class X: public A
,它在一些方法中只使用基类f(...)
和g(...)
。现在我想将X
中的方法扩展到A
的所有子类型:假设A
的子类型是B
,新类是class BX
。要求是:
- (实现(
class BX
应该使用class B
中的f(...)
和g(...)
,以及class X
中的所有方法 - (接口(
class BX
应与class A
的接口保持一致
我提出的解决方案是使用template<typename B> class BX: public B
来避免1中的钻石问题。
有更好的方法来实现我想要的吗?
根据我的经验,如果你只继承接口(即仅虚拟接口(并使用组合和委派来共享实现,那么继承的很多问题就会消失,然而,你在这里使用的奇怪的重复模板模式或CRTP是解决这个问题的另一种常见方法。
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
接口中的任何内容。
相关文章:
- 如何重构类层次结构以避免菱形问题
- C++ 中模板化类型的类层次结构
- 我的超类中的模板问题与结构定义
- 为什么不同类型层次结构的指针之间的dynamic_cast定义得很好?
- 继承层次结构并将元素添加到向量
- C++ 类层次结构中的"对齐"是什么意思?
- 相同的层次结构,访问基类的受保护成员时的行为不同
- 类层次结构中的运算符重载
- 如何在层次结构中实现运算符使用?
- 反向层次结构中的可变参数模板参数
- 如何在继承层次结构中调用具有默认参数的构造函数?
- C++ 提升 - 包含类层次结构对象的类的序列化
- 在C++继承层次结构时提取实现者
- 在C++中将类实例添加到对象层次结构中的问题
- 确定大层次结构中基本指针的实际类型,无需dynamic_cast
- 有关继承层次结构的问题,没有任何虚拟功能
- 类继承层次结构设计问题
- 循环包含,如何在不更改类层次结构的情况下解决此问题
- C++常见问题解答中类层次结构的打印模式
- gcc转储类层次结构问题