I have a class that uses one varibale that can have two different types according to a preprocessor directive (#ifdef #else #endif). How should I cleanly represent this variable's type without creating another UML class diagram?
You use the preprocessor to influence your class definition in a way comparable to this example:
class A {
#ifdef X
V myvar;
#else
W mywar;
#endif
...
};
This trick uses the preprocessor, playing with token substitution, instead of using a proper OOP design to achieve the same result.
UML does not know the preprocessor and doesn't provide for uch tricks. In UML you'll need to model an equivalent OOP construct to express what you want to do. Two main orientations can be considered:
«realization»
dependency (dotted line with triancle arrow head).The last option is the closest to what you do with the preprocessor, since it is compile time.
In C++ or other OOP languages, this kind of design could be implemented using the corresponding C++ implementation to the UML constructs above.
For class specialization (C++) you would have something like:
class U {...}; // a more general type that covers some specializations
class V:public U {...};
class W:public U {...};
class A {
U myvar; // ???
...
};
Unfortunately, this usually doesn't work so well due to the value semantic of C++ object model and slicing. So to make it work you'd need to go for a reference, a pointer, or petter a smart_pointer, for example:
class A {
unique_ptr<U> myvar; // smart pointer initialized in construtctor or intejected
...
};
This is very powerfull, and allows to decide at run-time with a (very) small performance overhead. But preprocessor is compile time, and there's a powerfull compile-time solution as well with templates:
template <class U>
class TA {
U myvar;
...
};
You may then in the code instantiate the class with the right type:
class TA<V> x,y,z;
class TA<W> a,b,c;
class TA<int> d,e,f; // no need to have a subtype relation
You may even make the code more readable, using type aliases like:
using A = class TA<V>; // instead of #define X
A x,y,z;