我有三个彼此紧密联系的类(class),我想同时专门研究这三个类(class)。这三个派生类应该使用与父类(super class)相同的接口(interface)相互通信,另外还要在派生版本中添加一些其他接口(interface)。我可以使用一种合理的模式在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的 vector ,并且FindValue应该返回CNewValue引用,等等。类似地,CGraph在其定义中引用CSeries,但是CNewGraph应该使用CNewSeries。

    最佳答案

    一种可能性是根据值类型对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进行交流的类,这会变得很麻烦。

    关于c++ - 如何在C++中同时子类化几个类?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12735564/

    10-09 05:43