一. 组合
组合关系: 组合关系代表着整体和部分具有相同的生命周期, 部分不能脱离整体而存在. 举一个最简单的例子(可能并不是很严谨):人和人的大脑之间的关系就是一种组合关系, 脱离了人体, 大脑不能单独存在, 人的生命周期结束, 大脑的生命周期随即结束.
组合关系的UML图如下所示:
上图表示class People和class Heart为一个组合关系, 可称为Heart组合到People上, 或者People由Heart组合而成.
使用C++来实现组合关系通常有两种方式:
1. 方式1
People.h
#include "Heart.h"
#include <string>
class People {
public:
People(std::string name, int count);
~People();
private:
std::string name;
Heart heart;
};
People.cpp
#include "People.h"
#include <iostream>
using namespace std;
People::People(std::string name, int count) : heart(count) {
this->name = name;
cout << __FUNCTION__ << endl;
}
People::~People() {
cout << __FUNCTION__ << endl;
}
Heart.h
class Heart {
public:
Heart(int count);
~Heart();
private:
int count;
};
Heart.cpp
#include "Heart.h"
#include <iostream>
using namespace std;
Heart::Heart(int count) {
cout << __FUNCTION__ << endl;
this->count = count;
}
Heart::~Heart() {
cout << __FUNCTION__ << endl;
}
test.cpp
#include "People.h"
#include <unistd.h>
int main() {
{
People("lh", 70);
}
sleep(30);
return 0;
}
简要的解释一下, 在People类中有两个成员变量, 一个是人的名字name, 另一个是Heart类对象heart. 在Heart类中有一个成员变量, 脉搏次数count. 在People的构造函数中,初始化人的姓名并且初始化Heart类对象heart. 在两个类的构造函数和析构函数中, 通过代码:
cout << __FUNCTION__ << endl;
来输出现在正在执行的函数.
通过测试代码可以得到如下结果:
由结果可得: Heart类的构造函数要比People类先执行, 并且在People完成析构之后,Heart也随即析构.满足组合关系, 被组合的对象随着主体的消亡而消亡.
ps:此处插入一个C++中构造函数执行顺序——1. 静态成员对象的构造函数(如果有的话, 全局仅调用一次构造函数) 2. 父类构造函数 3. 成员对象的构造函数(非静态成员) 4.自身构造函数
2. 方式2
People.h
#include "Heart.h"
#include <string>
class People {
public:
People(std::string name, int count);
~People();
private:
std::string name;
Heart *heart;
};
People.cpp
#include "People.h"
#include <iostream>
using namespace std;
People::People(std::string name, int count) {
this->name = name;
heart = new Heart(count);
cout << __FUNCTION__ << endl;
}
People::~People() {
delete heart;
cout << __FUNCTION__ << endl;
}
唯一的变化就是来自People类中的Heart对象变成了指针类型, 使用这种方式进行组合的时候需要注意的是, 在构造函数中要对被组合的对象new一个空间, 并且在析构函数中要手动delete这一块空间, 否则会违背组合关系“同生共死”的要求 .
测试结果如下:
总结:组合关系通俗来讲就是一种同生共死的关系,组合类和被组合的类具有相同的生命周期,被组合的类不可脱离主体而存在.