Как я могу одновременно разделить несколько классов в C ++?

У меня есть три класса, которые тесно связаны друг с другом, и я хотел бы специализировать все три одновременно. Три производных класса должны взаимодействовать друг с другом с теми же интерфейсами, что и суперклассы, плюс некоторые дополнительные интерфейсы, которые я добавлю в производные версии. Есть ли разумный шаблон, который я могу использовать для реализации такого рода отношений «одновременного вывода» в C ++?

Чтобы быть более конкретным: я расширяю компонент пользовательского интерфейса, который отображает и редактирует график. Участвуют три класса:

  • CGraph, сам виджет пользовательского интерфейса;
  • 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.

2

Решение

Одна из возможностей — шаблонизировать 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.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector