如何在C++中同时对几个类进行子类划分

How can I simultaneously subclass several classes in C++?

本文关键字:几个 划分 子类 C++      更新时间:2023-10-16

我有三个彼此紧密耦合的类,我想同时专门化这三个类。这三个派生类应该使用与超类相同的接口,加上我将在派生版本中添加的一些额外接口来相互通信。有没有一个合理的模式可以用来在C++中实现这种"同时派生"关系?

更具体地说:我正在扩展一个显示和编辑图形的UI组件。涉及三个类别:

  • CGraph,UI小部件本身
  • C系列,保存数据并由CGraph操作
  • CValue,表示系列中的一个值,其列表由C系列所有

我计划添加派生类CNewGraph、CNewSeries和CNewValue(占位符名称)。

CGraph     ---views/edits--->  CSeries     ---owns list of--->  CValue
^                              ^                                ^
| is-a                         | is-a                           | is-a
|                              |                                |
CNewGraph  ---views/edits--->  CNewSeries  ---owns list of--->  CNewValue

我遇到的问题是,例如,C系列在其定义中引用了CValue:

class CSeries
{
public:
CValue & FindValue(/* stuff */);
private:
vector<CValue> m_values;
};

在CNewSeries中,它应该是CNewValue的向量,FindValue应该返回CNewValue引用等。类似地,CGraph在其定义中引用了CSeries,但CNewGraph应该使用CNewSeries。

一种可能性是基于值类型对C系列进行模板化。然后,您可以创建一个派生类,指定要使用的特定值类型,如果不需要其他成员,甚至可以创建typedef。

template <typename T>
class CSeriesBase
{
public:
T & FindValue(/* stuff */);
private:
std::vector<T> m_values;
};
typedef CSeriesBase<CValue> CSeries;
class CNewSeries : public CSeriesBase<CNewValue>
{
/* additional members */
};

然而,这打破了继承关系,因此CNewSeries现在不是从C系列派生的。这意味着任何其他使用C系列的产品都无法无缝使用CNewSeries。特别是,CGraph也需要模板化,这次是在系列类型上。

template <typename T>
class CGraphBase
{
public:
void SetSeries(T * pSeries);
private:
T * m_pSeries;
};
typedef CGraphBase<CSeries> CGraph;
class CNewGraph : public CGraphBase<CNewSeries>
{
/* additional members */
};

对于只有三个类,这还不错,尽管我可以想象,如果有更多的类需要与C系列对话,它会变得很麻烦。