I have three classes that are closely coupled to each other, and I would like to specialize all three simultaneously. The three derived classes should talk to each other with the same interfaces as the superclasses, plus some additional interfaces I will add in the derived versions. Is there a reasonable pattern I can use to implement this kind of “simultaneous derivation” relationship in C++?
To be more specific: I’m extending a UI component that displays and edits a graph. There are three classes involved:
- CGraph, the UI widget itself;
- CSeries, which holds the data and is operated upon by CGraph;
- CValue, representing one value in the series, a list of which is owned by CSeries.
I plan to add derived classes CNewGraph, CNewSeries, and CNewValue (placeholder names).
CGraph ---views/edits---> CSeries ---owns list of---> CValue
^ ^ ^
| is-a | is-a | is-a
| | |
CNewGraph ---views/edits---> CNewSeries ---owns list of---> CNewValue
The kind of problem I run into with this is that CSeries, for instance, refers to CValue in its definition:
class CSeries
{
public:
CValue & FindValue(/* stuff */);
private:
vector<CValue> m_values;
};
In CNewSeries, that should be a vector of CNewValue instead, and FindValue should return a CNewValue reference, etc. Similarly, CGraph refers to CSeries in its definition, but CNewGraph should use CNewSeries instead.
One possibility is to templatize CSeries based on the value type. Then you can create a derived class that specifies a specific value type to use, or even a typedef if no additional members are needed.
However, this breaks the inheritance relationships, so CNewSeries now does not derive from CSeries. This means anything else that uses CSeries cannot seamlessly use CNewSeries. In particular, CGraph needs to be templatized as well, on the series type this time.
For only three classes, this is not too bad, though I can imagine it getting cumbersome in a hurry if you had many more classes needing to talk to CSeries.