2

互いに密接に関連する 3 つのクラスがあり、3 つすべてを同時に専門化したいと考えています。3 つの派生クラスは、スーパークラスと同じインターフェイスに加えて、派生バージョンに追加するいくつかの追加インターフェイスを使用して相互に通信する必要があります。この種の「同時派生」関係を C++ で実装するために使用できる合理的なパターンはありますか?

具体的には、グラフを表示および編集する UI コンポーネントを拡張しています。関連する 3 つのクラスがあります。

  • CGraph、UI ウィジェット自体。
  • データを保持し、CGraph によって操作される CSeries。
  • シリーズ内の 1 つの値を表す 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

1 つの可能性は、値の型に基づいて 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 をシームレスに使用できないことを意味します。特に、今回は series 型で 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 */
};

たった 3 つのクラスの場合、これはそれほど悪くはありませんが、CSeries と通信する必要があるクラスがさらに多くある場合、急いで面倒になることは想像できます。

于 2012-10-04T20:41:04.207 に答える