当前位置: 首页 > 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.lryc.cn/news/622133.html

相关文章:

  • 自定义数据集(pytorchhuggingface)
  • cut、tr、sort 和 uniq 生产典型示例
  • 微服务的编程测评系统11-jmeter-redis-竞赛列表
  • Nginx反向代理与缓存实现
  • 【论文解读】DDRNet:深度双分辨率网络在实时语义分割中的结构与原理全面剖析
  • 51单片机-驱动蜂鸣器模块教程
  • 开源数据发现平台:Amundsen Frontend Service 安装 开发者指南
  • debian13 安装过程 root配置
  • 从 LLM 到自主 Agent:OpenCSG 打造开源 AgenticOps 生态
  • Linux网络基础概念
  • 【RTOS】RT-Thread 进程间通信IPC源码级分析详解
  • [Pyro] 基础构件 | 随机性sample | 可学习参数param | 批量处理plate
  • 【3D图像技术分析及实现】3DGS与深度学习网络结合以实现跨场景迁移的研究调研
  • 电力系统之常见基础概念
  • 【秋招笔试】2025.08.15饿了么秋招机考-第二题
  • [激光原理与应用-285]:理论 - 波动光学 - 无线电磁波的频谱分配
  • [激光原理与应用-287]:理论 - 波动光学 - 电磁波既能承载能量,又能承载信息?
  • 力扣(接雨水)——单调栈
  • 在 Linux 服务器搭建Coturn即ICE/TURN/STUN实现P2P(点对点)直连
  • Vim 常用快捷键及插件
  • 力扣top100(day04-05)--堆
  • [Linux]双网卡 CentOS 系统中指定网络请求走特定网卡的配置方法
  • 微服务容错与监控体系设计
  • 基于Selenium的web自动化框架
  • 另类pdb恢复方式-2
  • 机器学习中的PCA降维
  • 【GPT入门】第47课 大模型量化中 float32/float16/uint8/int4 的区别解析:从位数到应用场景
  • ifcfg-ens33 配置 BOOTPROTO 单网卡实现静态和dhcp 双IP
  • break的使用大全
  • 102、【OS】【Nuttx】【周边】文档构建渲染:安装 Esbonio 服务器