2

In a file of my library I have a class that inherits from a template.

Example of my code:

class data{ ... };
class dataA: public data{ ... };
class dataB: public data{ ... };

//inheritance from a template

template<typename dataHandler>
class myClass: public dataHandler{ ... };

The template dataHandler in my code can be either data, dataA or dataB.

I would like to write an UML diagram for the class myClass making clear the inheritance form the previous datatype.

qwerty_so
  • 35,448
  • 8
  • 62
  • 86
GiulioPN
  • 21
  • 3
  • 1
    do you want `class myClass: public dataHandler{` or something else ? Your current inheritance is invalid – bruno Jun 03 '20 at 16:51
  • 1
    Supposing you want `template class myClass: public dataHandler {..}` it is easy to show `myClass --|> data` etc but for me you cannot have `myClass[dataHandler] --|> dataHandler` because *dataHandler* is not a template parameter out of the template class and that inheritance is invalid. If it is possible to model `myClass` inherits `X` this is throw a *constraint*, except if *X* must be *data* or *dataA* or *dataB* and in that case you just have to show `myClass --|> data` and `myClass --|> dataA` and `myClass --|> dataB` – bruno Jun 03 '20 at 18:03
  • @bruno Yes your right, I made a mistake during the copy and paste. I edit the question right now. – GiulioPN Jun 03 '20 at 18:16

2 Answers2

0

It seems it can't be done in UML. According to UML specification,

  1. Class is a kind of EncapsulatedClassifier - clause 11.4
  2. EncapsulatedClassifier is a kind of StructuredClassifier - clause 11.3
  3. StructuredClassifier is a kind of Classifier - clause 11.2
  4. Classifier is a kind of TemplateableElement - clause 9.2
  5. TemplateableElement is a kind of Element - clause 7.3

Thus Class is not a kind of TemplateParameter (clause 7.3).

Now suppose that you somehow managed to draw an UML diagram that says that myClass is a generalization of dataHandler. Then dataHandler is an instance of metaclass TemplateParameter so myClass must be too! But myClass is an instance of metaclass Class and Class is not a kind of TemplateParameter - contradiction. This contradiction proves that what you are asking for can't be done in UML.

zer0hedge
  • 449
  • 3
  • 12
  • The inheritance chain is perfect. But there is a misunderstanding in the conclusion:the relationship between parameter & bound element is not a subtyping: "*The TemplateSignature of a template defines a set of TemplateParameters that may be bound to actual model Elements in a bound element for the template*" means that the parameter may be bound to any suitable Element, including classes. In fact it is very common to bind parameters to classes; See clause 9.3.5 figure 9.5 where a class AddressList is bound to a parameter T. The issue is how to use substitution for inheritance. – Christophe Aug 13 '22 at 10:16
  • @Christophe I've updated the answer to make it clearer. Please have a look. – zer0hedge Aug 16 '22 at 15:42
0

Limits of UML templates

The problem that you encounter is related to the way UML deals with the substitution of template parameters with the bound elements. And this is primarily caused by the notation and not the inheritance.

In fact, if you would have a myClass with only composition:

template<typename T>
class myClass { 
   T a;
   vector<T> v; 
   ...
}; 
using myClassDataA = myClass<dataA>;

you could represent it in a self-contained way in UML with, the template parameter being used only within the template class:

enter image description here

But there is as far as I know, no way to templatize an equivalent expression of the same class, if you would like to show the T properties as association end:

enter image description here

And for the inheritance, it's the same issue: the inherited class is outside the template class. But here, there is no notational shortcut that could magically include it in the template box.

Visual workaround?

If it is mainly for graphical communication of a C++ design, you could suggest visually, that a group of classes all depend on the same template parameters. In my composition example above, it would look like:

enter image description here

For your inheritance situation it would be:

enter image description here

But keep in mind that there is no semantic defined in UML for that. For instance, nothing would allow an UML tool to identify all the members of myClass<dataA> that would be inherited from dataA. In other words, no UML code generator or tool would be able to produce something meaningful with the models, but fellow C++ programmers will perfectly understand what you mean.

Better design?

While your template construction is very powerful, it is also very error prone as the operations that you can perform on the instantiation of the same template, would depend on the bindings. This means that you would need different test cases for every single instantiation of the template.

So it's worth to remind the general principle:

Prefer composition over inheritance

So just create a dataHandler member in your template class, and forward a set of well-identified operations that should be common to all handlers to this member. You then could model it in UML without difficulty using the existing UML semantics.

I know, it's not so flexible; but I think the little extra hassle for the operation forwarding, will save you a lot of troubles later. If really you need more flexibility, you could also think to invert the inheritance using CRTP but this time with a much clearer and unambiguous UML modeling.

Christophe
  • 68,716
  • 7
  • 72
  • 138