目录
组合(复合)
定义
举例
依赖
定义
举例
关联
定义
举例
聚合
定义
举例
组合(复合)
定义
它是一种"is a part of"的关系,部分与整体,包含与被包含。组合是一个类中包含另一个类对象。相比聚合,组合是一种强所属关系,组合关系的两个对象往往具有相同的生命周期,被组合的对象是在组合对象创建的同时或者创建之后创建,在组合对象销毁之前销毁。一般来说被组合对象不能脱离组合对象独立存在,整体不存在,部分一定不存在。
举例
人与手、人与头之间的关系,人需要包含头和手,头。手是人的一部分且不能脱离人独立而存在。
在C++语法中,通常在组合类中包含被组合类对象来实现组合关系:
class CHand {
public:
void move() {
cout << "我的小手不断地移动" << endl;
}
};
class CPeople {
public:
CHand m_hand;
public:
void clap() {
m_hand.move();
cout << "撞击...发出掌声" << endl;
}
};
{//组合复合
CPeople peo;
peo.clap();
}
依赖
定义
它是一种"uses a"的关系。一个对象的某种行为依赖于另一个类对象,被依赖的对象视为完成某个功能的工具,并不持有对他的引用,只有完成某个功能的时候才会用到,而且是必不可少的。依赖之间是没有生命周期约束关系的。
举例
人要完成编程这件事,那么需要用到电脑,电脑作为一个工具,其他的时候不需要,电脑也不可能作为人的属性而存在(非组合关系),人必须依赖于电脑才能完成编程这件事。
C++语法中,代码的表现形式为多种,通常将被依赖的对象作为另一类方法的参数的形式实现两个类之间的依赖关系:
class CComputer {
public:
void compile() {
cout << "编译代码...生成可执行程序" << endl;
}
};
void coded(CComputer* pComp) {
if (!pComp)return;
m_hand.move();
cout << "敲出一行行代码..." << endl;
pComp->compile();
}
{//依赖
CComputer comp;
CPeople peo;
peo.coded(&comp);
peo.coded(nullptr);
}
关联
定义
它是一种"has a"的关系。关联不是从属关系,而是平等关系,可以拥有对方,但不可占有对方。完成某个功能与被关联的对象有关,但可有可无,被关联的对象与关联对象无生命周期约束关系,被关联对象的生命周期由谁创建就由谁来维护。只要二者同意,可以随时解除关系或是进行关联,被关联的对象还可以再被别的对象关联,所以关联是可以共享的。
举例
人和朋友的关系,人要完成游戏这个功能,没有朋友可以自己玩游戏,如果交到朋友了就可以和朋友一起玩游戏。
C++语法中,通常在关联的类中定义被关联类对象的指针形式实现两个类之间的关联关系。
class CFriend {
public:
void play() {
cout << "我的朋友正在玩耍" << endl;
}
};
CFriend* m_pFri;
CPeople(): m_pFri(nullptr){
//m_pFri = nullptr;
}
void playGame() {
if (m_pFri) {//有朋友
m_pFri->play();
cout << "我带着朋友一起玩" << endl;
cout << "轻松拿下五杀" << endl;
}
else {//没有朋友
cout << "我自己孤独的玩耍" << endl;
cout << "勉强拿下五杀" << endl;
}
}
{//关联
CPeople peo;
peo.playGame();
CFriend fri;
peo.m_pFri = &fri;//交朋友了
peo.playGame();
}
聚合
定义
它是一种"owns a"的关系。多个被聚合的对象聚集起来形成一个大的整体,聚合的目的是为了统一进行管理同类型的对象,聚合是一种弱所属关系,被聚合的对象还可以再被别的对象关联,所以被聚合对象是可以共享的。虽然是共享的,聚合代表的是一种更亲密的关系,相当于强版本的关联。
举例
一堆人组成一个家庭,进行统一管理完成玩游戏的功能。
C++语法中,通常在聚合类中定义被聚合对象指针的数组、链表等容器。
class CFamily {
public:
CPeople* arr[10];
public:
CFamily() {
for (CPeople*& pPeo : arr) {
pPeo = nullptr;
}
arr[0] = new CPeople;
arr[1] = new CPeople;
arr[2] = new CPeople;
}
~CFamily() {
for (CPeople*& pPeo : arr) {
if (pPeo)
delete pPeo;
pPeo = nullptr;
}
}
void AllPeoplePlay() {
for (CPeople*& pPeo : arr) {
if (pPeo)
pPeo->playGame();
}
}
};
注意:在强类型的for中要对数组中的成员进行赋值或删除等操作时,返回类型后要加引用&,如果不加引用就是对pPeo赋值。而不是对数组内成员赋值,只有将pPeo变为数组成员的小名,对其赋值才能传递到数组成员。
{//聚合
CFamily fam;
fam.AllPeoplePlay();
}