C++复合关系

C++复合关系

  • 方式一:
  • 方式二:
  • 方式三:
  • 方式四:

Reference:
1.正确处理类的复合关系------新标准c++程序设计
2.程序设计与算法(三)C++面向对象程序设计

假设要编写一个小区养狗管理程序,该程序需要一个“主人”类,还需要一个“狗”类。狗是有主人的,主人也有狗。假定狗只有一个主人,但一个主人可以有最多10条狗。该如何处理“主人”类和“狗”类的关系呢?

方式一:

#include
class CMaster
{
    CDog dogs[10];
    int dog_num;
};
class CDog
{
    CMaster m;
};
int main()
{
}

这种写法是无法通过编译的。因为尽管提前对CDog类进行了声明,但编译到第4行时,编译器还是不知道CDog类的对象是什么样的,所以无法编译定义dog对象的语句。而且这种“人中有狗,狗中有人”的做法导致了循环定义

如果问这个CMaster对象有多少个字节,那么会说里面有10个CDog对象,所以它的体积是10倍的CDog体积。那么一个CDog对象占多少个字节呢:一个CDog对象包含一个CMaster对象,那么它的体积应该跟一个CMaster对象一样,这样就循环定义了,根本就算不出CMaster和CDog的体积。所以这种做法编译的时候就过不了。

方式二:

避免循环定义的方法是在一个类中使用另一个类的指针,而不是对象作为成员变量。即,为“狗”类设一个“业主”类的成员对象;为“业主”类设一个“狗”类的对象指针数组。

class CDog;
class CMaster
{
    CDog* dogs[10];
    int dog_num;
};
class CDog
{
    CMaster m;
};
int main()
{
}

上面这种写法在第4行定义了一个CDoge类的指针数组为CMAster类的成员对象。指针就是地址,所以编译器编译到此时不需要知道CDog类是什么样子的。这种写法的思想是:当一个CMAster对象养了一条狗时,就有new运算符动态分配一个CDog类的对象,然后在dogs数组中找到一个元素,让它指向动态分配的CDog对象。

这种方式就避免了循环定义。CMaster有多少个字节能算出来,因为它里面有一个10个元素的数组,每一个元素都是一个指针,那它的字节数就是40个字节。同理CDog对象有多少个字节,也能自己算出来。

这种写法还是 不正确的。问题出在CDog对象中包含了CMaster对象。在多条狗的主人相同的情况下, 多个CDog对象中的CMaster对象都代表同一个主人,即同一个主人用了多个CMaster对象。这就造成了没有必要的冗余——一个主人用一个CMaster对象表示足矣,没有必要对应与多个CMaster对象。而且,在一对多的情况下,当主人的个人信息发生变化时,就需要将与其对应的、位于多个CDog对象中的CMaster成员变量m都找出来修改,这毫无必要,而且麻烦。
C++复合关系_第1张图片

方式三:

一个凑合的写法为,为“狗”类设一个“业主”类的对象指针;为“业主”类设一个“狗”类的对象数组:

class CMaster;//CMaster必须提前声明,
			//不能先写CMaster类后写CDog类
class CDog
{
	CMaster* pm;
};
class CMaster
{
	CDog dogs[10];
	int dog_num;
};
int main()
{
}

这样,主人相同的多个CDog,其pm指针都指向同一个CMaster对象。这种写法在三个地方存在问题:

  1. 从逻辑上讲,这不好在,从复合关系上讲,如果一个类有一个成员对象,那么我们会要求这个成员对象是这个类的固有属性。在这里面,主人类里面有10条狗,好像不能说狗是主人的一部分,或者狗是人的固有属性。
  2. 在这种做法里,狗狗失去了自由。因为所有的狗的对象都被包含在了一个或者多个主人对象里了,那么要对狗对象进行操作的话,必须就要通过它们的主人来进行。这样狗狗就没有了自由,不能进行独立的活动。
  3. 实际上,一个主人未必都养10条狗,这样会浪费掉一部分的空间。
    C++复合关系_第2张图片

方式四:

正确的写法为:
为“狗”类设一个“业主”类的对象指针;
为“业主”类设一个“狗”类的对象指针数组。

class CMaster;
class CDog
{
	CMaster* pm;
};
class CMaster
{
	CDog* dogs[10];
} 
int main()
{
}

这样的话,一个业主里面的成员变量dogs数组里面的有一些元素,就会指向主人所拥有的狗。在一些教科书上面,把这样一个类,有一个成员是另外一个类的指针的情况,称之为这两个类是知道的关系。因为一个类的对象通过指针就能知道(找到)另外一个类的对象。

这样的话,主人有多条狗,所以它不同的指针,指向他的多条狗。然后每一条狗都有一个指针指向它的主人,这样的话主人通过指针就能找到自己的狗并对狗进行操作。狗也能自己进行自由活动,而且通过狗的指针,也能找到它自己的主人。
C++复合关系_第3张图片

你可能感兴趣的:(C/C++,c++,数据结构)