2

我有三个彼此紧密耦合的课程,我想同时专攻这三个课程。三个派生类应该使用与超类相同的接口相互通信,另外还有一些我将在派生版本中添加的额外接口。是否有一种合理的模式可以用来在 C++ 中实现这种“同时推导”关系?

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

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

我计划添加派生类 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

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

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

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

4

1 回答 1

0

一种可能性是根据值类型对 CSeries 进行模板化。然后,您可以创建一个派生类来指定要使用的特定值类型,如果不需要其他成员,甚至可以创建 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 现在不是从 CSeries 派生的。这意味着任何其他使用 CSeries 的东西都不能无缝地使用 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 */
};

对于只有三个课程,这还不算太糟糕,尽管我可以想象如果您有更多课程需要与 CSeries 对话,它会变得很麻烦。

于 2012-10-04T20:41:04.207 回答