让A类和B类继承C类。所有这些都与main类的方法main一起在file.cpp中。如果我想创建一个classe A的实例,那么......
file.cpp
class C{
}
class A : public C{
}
class B : public C{
}
class Main{
.
.
.
void main(){
C *c = new A();
}
}
图表UML是
现在,假设我有相同的类,但每个类在不同的文件中。如果我想实例化A类,如上所述,我会在Main类中插入一个#include A.h指令,这会在我的图中产生一个依赖:
我的问题是:如果我想这样做,哪种情况是正确的?或者我在C ++中解释错误的UML关系?
答案 0 :(得分:1)
您需要使用合成关系来显示 Main
具有C
的实例。
我从未记录需要包含哪些文件,因为假设您需要一个位于另一个文件中的类的功能,您可能需要一个包含。
编辑:实际上,没有组合,因为您Main
类似乎有一个名为main()
的方法,它创建了一个实例C
类,而不是其成员。
答案 1 :(得分:1)
我认为它不需要像第二张图中那样具有has-a关系,因为它是隐含的。
A是-a a C,B是-a C,Main是-a C.
它更多地是关于您的设计结构而不是文件中的包含。
答案 2 :(得分:1)
首先,你不应该把代码放在.h文件中,除非你知道你在做什么(见inline functions,主要用于速度)
然后在main.h中,您不需要任何对A的引用。但是,在main.cpp中,您需要包含A.h.请记住,UML与语言无关,它用于绘制“谁与谁交谈”,而不是“谁与谁编译”。
通常情况下,c ++编译器会为每个cpp文件生成一个输出文件(使用gcc这些是.o文件,Visual Studio也会这样做但是透明)。然后,所有输出文件将在您的应用程序或库中合并(大部分时间),然后才能将您的函数链接在一起。
您可能还想查看forward references。它告诉编译器(而不是链接器)“这个类确实存在,你现在可能不知道它,但我向上帝发誓,它将存在于链接器输出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之间产生更多的耦合,这会产生自身的问题,但更接近于factory pattern