1

假设是 A 和 B 类,它们是 C 类的继承。所有这些都与 Main 类的方法 main 一起位于 file.cpp 中。如果我想创建一个 A 类的实例,那么......

文件.cpp

 class C{
 }

 class A : public C{
 }

 class B : public C{
 }
 class Main{
 .
 .
 .
 void main(){
    C *c = new A();
 }
 }

图 UML 在哪里

在此处输入图像描述

现在,假设我有相同的类,但每个类都在不同的文件中。如果我想实例化类 A,如上所述,我将在 Main 类中插入一个 #include Ah 指令,这将在我的图表中显示一个依赖项:

我的问题是:如果我想这样做,哪种情况是正确的?或者我在 C++ 中解释错误的关系 UML?

在此处输入图像描述

4

3 回答 3

1

您需要使用组合关系来显示Main has-a 的实例C

我从来没有记录过哪些文件需要被包含,因为假设如果你需要一个存在于另一个文件中的类的功能,你可能需要一个包含。

编辑:实际上,没有组合,因为看起来你Main的类有一个调用的方法main(),它创建C类的实例,而不是成员本身。

于 2013-02-15T02:09:19.033 回答
1

我认为它不需要像第二个图中那样具有has-a 关系,因为它是隐含的。

A is-a a C, B is-a C and Main has-a C.

它更多地是关于你的设计结构而不是你的文件中包含的内容。

于 2013-02-15T02:26:54.053 回答
1

首先,除非您知道自己在做什么,否则不应将代码放在 .h 文件中(请参阅内联函数,主要用于提高速度)

然后在 main.h 中,您不需要对 A 的任何引用。然而,在 main.cpp 中,您将需要包含 Ah 请记住,UML 与语言无关,它用于绘制“谁与谁交谈”而不是“谁与谁编译”。

通常情况下,您的 c++ 编译器将为每个 cpp 文件生成一个输出文件(使用 gcc 这些是 .o 文件,Visual Studio 也这样做,但透明地)。然后,所有输出文件将在您的应用程序或库中(大部分时间)合并在一起,然后您的函数才会链接在一起。

您可能还想查看前向引用。它是告诉编译器(而不是链接器)“这个类确实存在,你现在可能不知道它,但我向上帝发誓,它会存在于链接器输出 blob 中”。

在您的特定情况下,无论您是仅使用一个还是多个 cpp 文件,我都会像您的第二个示例一样绘制类图。您的主要课程确实知道 A。

现在想象你的 C 类有类似的方法

A* C::createA()
{
    return new A;
}

B* C::createB()
{
    return new B;
}

那么你的主要课程会有

int main()
{
    C* instance1 = C::createA();
    C* instance2 = C::createB();
}

在这种情况下,您的主类将失去 A 和 B 的所有亲密知识,这与您的第一个图表一致。这当然会在 A、B 和 C 之间产生更多的耦合,这会带来自己的问题,但更接近于工厂模式

于 2013-02-15T03:19:09.300 回答