C++:根据预处理器指令,用两种不同的可能类型表示 class 图中的变量
C++: Represent variable in class diagram with two different possible types depending on preprocessor directive
我有一个 class,它使用一个变量,根据预处理器指令 (#ifdef #else #endif),该变量可以有两种不同的类型。我应该如何在不创建另一个 UML class 图的情况下清楚地表示此变量的类型?
预处理器技巧与 OOP 设计
您使用预处理器以类似于此示例的方式影响您的 class 定义:
class A {
#ifdef X
V myvar;
#else
W mywar;
#endif
...
};
这个技巧使用预处理器,使用令牌替换,而不是使用适当的 OOP 设计来获得相同的结果。
问题的 UML 方面
UML 不了解预处理器,也不提供此类技巧。在 UML 中,您需要对等效的 OOP 构造建模以表达您想要执行的操作。可以考虑两个主要方向:
- 你会为一个 generalization U 建立专业化 V 和 W 的模型。你会为 A 与 U 的关联建立模型。这将涵盖你的设计,尽管它更灵活,因为它允许选择U 在运行时。
- 如果您使用带有接口的语言,您通常会将 U 定义为在接口中,而 V 和 W 将显示
«realization»
dependency(带三角形箭头的虚线)。
- 您将使用 UML templates 和参数化类型 U 的绑定对模板建模。
最后一个选项最接近您对预处理器所做的操作,因为它是编译时间。
有关预处理器的 C++ 替代方案的更多信息
在 C++ 或其他 OOP 语言中,可以使用与上述 UML 结构相应的 C++ 实现来实现这种设计。
对于 class 专业化 (C++) 你会得到类似的东西:
class U {...}; // a more general type that covers some specializations
class V:public U {...};
class W:public U {...};
class A {
U myvar; // ???
...
};
不幸的是,由于 C++ 对象模型和切片的值语义,这通常不能很好地工作。因此,要使其正常工作,您需要获取参考、指针或输入 smart_pointer,例如:
class A {
unique_ptr<U> myvar; // smart pointer initialized in construtctor or intejected
...
};
这非常强大,允许在 run-time 以(非常)小的性能开销做出决定。但是预处理器是编译时间,还有一个强大的 compile-time 解决方案以及模板:
template <class U>
class TA {
U myvar;
...
};
然后您可以在代码中用正确的类型实例化 class:
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
您甚至可以使用类型别名使代码更具可读性,例如:
using A = class TA<V>; // instead of #define X
A x,y,z;
我有一个 class,它使用一个变量,根据预处理器指令 (#ifdef #else #endif),该变量可以有两种不同的类型。我应该如何在不创建另一个 UML class 图的情况下清楚地表示此变量的类型?
预处理器技巧与 OOP 设计
您使用预处理器以类似于此示例的方式影响您的 class 定义:
class A {
#ifdef X
V myvar;
#else
W mywar;
#endif
...
};
这个技巧使用预处理器,使用令牌替换,而不是使用适当的 OOP 设计来获得相同的结果。
问题的 UML 方面
UML 不了解预处理器,也不提供此类技巧。在 UML 中,您需要对等效的 OOP 构造建模以表达您想要执行的操作。可以考虑两个主要方向:
- 你会为一个 generalization U 建立专业化 V 和 W 的模型。你会为 A 与 U 的关联建立模型。这将涵盖你的设计,尽管它更灵活,因为它允许选择U 在运行时。
- 如果您使用带有接口的语言,您通常会将 U 定义为在接口中,而 V 和 W 将显示
«realization»
dependency(带三角形箭头的虚线)。 - 您将使用 UML templates 和参数化类型 U 的绑定对模板建模。
最后一个选项最接近您对预处理器所做的操作,因为它是编译时间。
有关预处理器的 C++ 替代方案的更多信息
在 C++ 或其他 OOP 语言中,可以使用与上述 UML 结构相应的 C++ 实现来实现这种设计。
对于 class 专业化 (C++) 你会得到类似的东西:
class U {...}; // a more general type that covers some specializations
class V:public U {...};
class W:public U {...};
class A {
U myvar; // ???
...
};
不幸的是,由于 C++ 对象模型和切片的值语义,这通常不能很好地工作。因此,要使其正常工作,您需要获取参考、指针或输入 smart_pointer,例如:
class A {
unique_ptr<U> myvar; // smart pointer initialized in construtctor or intejected
...
};
这非常强大,允许在 run-time 以(非常)小的性能开销做出决定。但是预处理器是编译时间,还有一个强大的 compile-time 解决方案以及模板:
template <class U>
class TA {
U myvar;
...
};
然后您可以在代码中用正确的类型实例化 class:
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
您甚至可以使用类型别名使代码更具可读性,例如:
using A = class TA<V>; // instead of #define X
A x,y,z;