当前位置: 首页 > news >正文

C++设计模式:类间关系

类封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性、操作、关系的对象集合的总称。在系统中,每个类都具有一定的职责,职责指的是类要完成什么样子的功能,要承担什么样子的义务。一个类可以有多种职责,但是设计得好的类一般只有一种职责。

类与类之间的关系

继承关系

继承也叫作泛化(Generalization),子类(派生类)继承父类(基类)的属性和方法,并可扩展或重写父类功能。

C++ 中没有专门的 “接口” 关键字,通常用纯虚基类模拟接口,子类通过 public 继承该纯虚类并实现其所有纯虚函数。

class Bird
{
public:string getName(){return m_name;}void setName(string name){m_name = name;}virtual void fly() {}virtual void eat() {}
protected:string m_sex;string m_name;
};class Cuckoo : public Bird
{
public:void fly() override{cout << "我拍打翅膀飞行..." << endl;}void eat() override{cout << "我喜欢吃肉肉的小虫子..." << endl;}
};class Eagle : public Bird
{
public:void fly() override{cout << "我展翅翱翔..." << endl;}void eat() override{cout << "我喜欢吃小动物..." << endl;}
};

 组合关系

组合(Composition)表示 “整体 - 部分” 关系,部分完全依赖整体存在(强包含)。

部分不能脱离整体独立存在,整体的生命周期决定部分的生命周期(整体创建时部分被创建,整体销毁时部分也被销毁),部分只能属于一个整体。
例如人和心脏:心脏是人的一部分,人死亡后心脏也不再独立存在。

class Heart {
public:void beat() {}
};
class Person {
private:Heart heart; // 组合关系(部分作为成员变量,随整体创建/销毁)
public:Person() : heart() {} // 构造时创建心脏
};

 聚合关系

聚合(Aggregation)表示 “整体 - 部分” 关系,部分可脱离整体独立存在(弱包含)。

整体通过成员变量持有部分的指针 / 引用,整体包含部分,但部分的生命周期不由整体控制,部分可属于多个整体。

比如公司和员工:员工是公司的一部分,但员工可离职(脱离公司存在)。

class Employee {};
class Company {
private:std::vector<Employee*> employees; // 聚合员工(部分)
public:void addEmployee(Employee* e) {employees.push_back(e);}
};

关联关系

表示两个类之间存在长期、稳定的连接,通常体现为一个类持有另一个类的对象引用(或指针)。

关系可单向或双向(如 A 关联 B,或 A 与 B 相互关联),类之间生命周期相互独立,关联不影响对象的创建与销毁。

单向关联

单向关联指的是关联只有一个方向,比如每个孩子都拥有一个Parent,其代码实现为:

class Parent
{
};class Child
{
private:Parent m_father;
};
双向关联

现实生活中每个孩子都有父母,每个父母同样有自己的孩子,如果想要通过类来描述这样的亲情关系,代码如下:

class Parent
{
private:Child* m_son;
};class Child
{
private:Parent* m_father;
};
自关联

自关联指的就是当前类中包含一个自身类型的对象成员,这在链表中非常常见,单向链表中都会有一个指向自身节点类型的后继指针成员,而双向链表中会包含一个指向自身节点类型的前驱指针和一个指向自身节点类型的后继指针。就以双向链表节点类为例,它的C++写法为:

class Node 
{
private:void* m_data;Node* m_prev;Node* m_next;
};

 依赖关系

表示一个类(依赖方)在执行特定操作时,临时需要另一个类(被依赖方)的协助,是一种短期的 “使用” 关系。

通常通过方法参数、局部变量或静态方法调用体现,无长期持有关系,操作结束后依赖消失。

例如计算器计算时需要临时使用数字Number对象:

class Number {
public:int value;
};
class Calculator {
public:// 通过参数依赖 Numberint add(Number a, Number b) { return a.value + b.value; }
};

总结

类之间的关系强弱顺序是这样的:继承(含接口实现) >  组合  >  聚合  >  关联  >  依赖。

在实际设计中,应优先使用低耦合关系(如关联、聚合、组合),避免过度依赖继承,以提高代码的灵活性和可维护性。

http://www.dtcms.com/a/332352.html

相关文章:

  • Linux Namespace隔离实战:dd/mkfs/mount/unshare构建终极沙箱
  • PCB沉金工艺解析:高端电子制造的可靠基石
  • 推荐一款高性能状态机管理解决方案
  • Java ArrayList的介绍及用法
  • OpenCV Python——VSCode编写第一个OpenCV-Python程序 ,图像读取及翻转cv2.flip(上下、左右、上下左右一起翻转)
  • MySQL知识点(上)
  • adb 发送广播
  • dockerfile自定义镜像,乌班图版
  • 高并发接口性能优化实战:从200ms到20ms的蜕变之路
  • 线索转化率翻3倍?AI重构CRM
  • Uniapp之微信小程序自定义底部导航栏形态
  • 北京JAVA基础面试30天打卡10
  • 数据资产运营——解读 167页 2025 县域数据资产运营蓝皮书【附全文阅读】
  • 5G工业一体机汽车零部件工厂的无纸化管理
  • [激光原理与应用-285]:理论 - 波动光学 - 无线电磁波的频谱分配
  • [激光原理与应用-286]:理论 - 波动光学 - 不同频段电磁波的特点与差异性
  • 局部变量与全局变量的关系及应用
  • 46.Sentinel规则持久化
  • FreeRTOS中断服务程序(ISR)详细讲解
  • 从ChatGPT到智能助手:Agent智能体如何颠覆AI应用
  • 基于uiautomation的自动化流程RPA开源开发演示
  • 机器学习——PCA(主成分分析)降维
  • 开源 Arkts 鸿蒙应用 开发(十五)自定义绘图控件--仪表盘
  • STM32 - Embedded IDE - GCC - 解决LWRB库在GCC编译器会编译失败,在ARMCC编译器时却正常编译
  • 【GUI】ssh实现gui本地可视
  • 公司的服务器怎么个事,服务器是什么东西
  • 系统思考:情绪内耗与思维模式
  • 开源长期记忆 短期记忆 框架调研对比19999字
  • 4.4 vue3生命周期函数
  • 解决在uniapp真机运行上i18n变量获取不到问题