C++设计模式笔记(内附可运行代码示例)

持续更新, 欢迎关注.......

前言

设计目的

高内聚,低耦合

设计原则

1、开放封闭原则

类的改动是通过增加代码进行,而不是修改源代码。

2、单一职责原则

职责单一,对外只提供一种功能,引起类变化的原因都应该只有一个。

3、依赖倒置原则

依赖于抽象,不要依赖于具体实现,也就是针对接口编程。

4、接口隔离原则

一个接口应该只提供一种对外功能,不应该把所有操作都封装到一个接口中。

5、里氏替换原则

任何抽象类出现的地方都可以用他的实现类进行替换。实际就是虚拟机制,语言级别实现面向对象功能。

6、优先使用组合而不是继承

7、迪米特法则

一个对象应该对其他对象尽可能少的了解,从而降低各个对象之间的耦合。

UML类图

参考UML类图几种关系的总结_在类图中,类与类-CSDN博客

创建型模式

单例模式

场景

- 在多个线程之间, 比如初始化一次 socket 资源; 比如 servlet 环境, 共享同一个资源或者
操作同一个对象

- 在整个程序空间使用全局变量, 共享资源
- 大规模系统中, 为了性能的考虑, 需要节省对象的创建时间等等。

核心要点

a) 构造函数私有化
b) 提供一个全局的静态方法(全局访问点)
c) 在类中定义一个静态指针, 指向本类的变量的静态变量指针

示例

懒汉式

构造延时到使用Instance时

#include <iostream>
using namespace std;
//懒汉式
class Singelton {
private:Singelton(){m_singer = NULL;m_count = 0;cout << "构造函数 Singelton ... do" << endl;}
public:static Singelton *getInstance(){if (m_singer == NULL ) //懒汉式: 1 每次获取实例都要判断 2 多线程会有问题{m_singer = new Singelton;}return m_singer;}static void printT(){cout << "m_count: " << m_count << endl;}
private:static Singelton *m_singer;static int m_count;
};Singelton *Singelton::m_singer = NULL; //懒汉式 并没有创建单例对象
int Singelton::m_count = 0;int main()
{cout << "演示 懒汉式" << endl;Singelton *p1 = Singelton::getInstance(); //只有在使用的时候, 才去创建对象。Singelton *p2 = Singelton::getInstance();if (p1 != p2) {cout << "不是同一个对象" << endl;} else {cout << "是同一个对象" << endl;}p1->printT();p2->printT();return 0;
}

运行结果:

演示 懒汉式
构造函数 Singelton ... do
是同一个对象
m_count: 0
m_count: 0
饿汉式

直接编译时就构造

#include <iostream>
using namespace std;class Singelton2
{private:Singelton2(){m_singer = NULL;m_count = 0;cout << "构造函数 Singelton ... do" << endl;}public:static Singelton2 *getInstance(){// if (m_singer == NULL )// {// m_singer = new Singelton2;// }return m_singer;}static void FreeInstance(){if (m_singer != NULL){delete m_singer;m_singer = NULL;m_count = 0;}}static void printT(){cout << "m_count: " << m_count << endl;}
private:static Singelton2 *m_singer;static int m_count;
};Singelton2 *Singelton2::m_singer = new Singelton2; //不管你创建不创建实例, 均把实例 new出来
int Singelton2::m_count = 0;int main()
{cout << "演示 饿汉式" << endl;Singelton2 *p1 = Singelton2::getInstance(); //只有在使用的时候, 才去创建对象。Singelton2 *p2 = Singelton2::getInstance();if (p1 != p2) {cout << "不是同一个对象" << endl;} else {cout << "是同一个对象" << endl;}p1->printT();p2->printT();Singelton2::FreeInstance();Singelton2::FreeInstance();return 0;
}

运行结果:

构造函数 Singelton ... do
演示 饿汉式
是同一个对象
m_count: 0
m_count: 0

简单工厂模式

场景

核心

1、工厂角色 --负责创建所有实例

工厂类是整个模式的关键,需要包含判断逻辑,能够根据外界给定的信息,决定创建哪个具体类的对象

2、抽象角色 --创建的所有对象的父类

3、具体产品角色 --具体实例对象

示例

工厂类里一定有选择逻辑

#include <iostream>
#include <cstring>
using namespace std;
//思想: 核心思想是用一个工厂, 来根据输入的条件产生不同的类, 然后根据不同类的 virtual函数得到不同的结果。
//元素分析:
//抽象产品类: 水果类
//具体的水果类: 香蕉类、 苹果类、 梨子
//优点 适用于不同情况创建不同的类时
//缺点 客户端必须要知道基类和工厂类, 耦合性差 增加一个产品, 需要修改工厂类
class Fruit {
public:virtual void getFruit() = 0;
protected:
private:
};class Banana : public Fruit {
public:virtual void getFruit(){cout<<"香蕉"<<endl;}
protected:
private:
};class Pear : public Fruit {
public:virtual void getFruit(){cout<<"梨子"<<endl;}
protected:
private:
};class Factory
{
public:static Fruit* Create(char *name){Fruit *tmp = NULL;if (strcmp(name, "pear") == 0){tmp = new Pear();} else if (strcmp(name, "banana") == 0) {tmp = new Banana();} else {return NULL;}return tmp;}
protected:
private:
};int main() {Fruit *pear = Factory::Create("pear");if (pear == NULL) {cout << "创建 pear 失败\n";}pear->getFruit();Fruit *banana = Factory::Create("banana");banana->getFruit();return 0;
}

 运行结果

梨子
香蕉

 工厂模式

场景

核心

1、抽象工厂(Creator) 角色                                                                                                  ---工厂方法模式的核心, 任何工厂类都必须实现这个接口。
2、具体工厂( Concrete Creator) 角色
---具体工厂类是抽象工厂的一个实现, 负责实例化产品对象。
3、抽象(Product) 角色
---工厂方法模式所创建的所有对象的父类, 它负责描述所有实例所共有的公共接口。
4、具体产品(Concrete Product) 角色
---工厂方法模式所创建的具体实例对象

和简单工厂模式不同:

a) 多了个抽象工厂类,每个具体工厂类统一来自抽象工厂

b) 添加新的产品对象时,只需添加一个具体对象和一个具体工厂

示例

1、抽象工厂:FruitFactory,具体工厂:BananaFactory、AppleFactory

2、抽象产品:Fruit,具体产品:Banana、Apple

3、main函数调用具体工厂时只是先把具体工厂创建出来,然后通过工厂的GetFruit创建具体对象

#include "iostream"
using namespace std;class Fruit
{
public:virtual void sayname(){cout<<"fruit\n";}
};class FruitFactory
{
public:virtual Fruit* getFruit(){return new Fruit();}
};
//香蕉
class Banana : public Fruit
{
public:virtual void sayname(){cout<<"Banana \n"<<endl;}
};
//香蕉工厂
class BananaFactory : public FruitFactory
{
public:virtual Fruit* getFruit(){return new Banana;}
};//苹果
class Apple : public Fruit
{
public:virtual void sayname(){cout<<"Apple \n"<<endl;}
};//苹果工厂
class AppleFactory : public FruitFactory
{
public:virtual Fruit* getFruit(){return new Apple;}
};int main()
{FruitFactory * ff = NULL;Fruit *fruit = NULL;//1 香蕉ff = new BananaFactory(); // 1、先创建具体工厂fruit = ff->getFruit(); // 2、通过具体工厂创建具体对象fruit->sayname();delete fruit;delete ff;//2 苹果ff = new AppleFactory();fruit = ff->getFruit();fruit->sayname();delete fruit;delete ff;cout<<"hello....\n";return 0;
}

运行结果:

Banana Apple hello....

抽象工厂模式

场景

可以一下生产一个产品族

核心

注意:上图的ConcreteFactory存在漏画问题,应该是CreateProductA(): AbStractProductA 和 CreateProductB(): AbStractProductB

1、抽象工厂角色

2、具体工厂角色

3、抽象产品角色

4、具体产品角色

示例

抽象工厂类:FruitFactory,具体工厂类:NorthFruitFactory、SourthFruitFactory;

抽象产品类:Fruit,具体产品类:SouthBanana/SouthApple/NorthBanana/NorthApple。

GetFruit切换成了GetApple、GetBanana,所以可以建立产品族。

#include "iostream"
using namespace std;class Fruit
{
public:virtual void sayname(){cout<<"fruit\n";}
};class FruitFactory
{
public:virtual Fruit* getApple(){return new Fruit();}virtual Fruit* getBanana(){return new Fruit();}
};
//南方香蕉
class SouthBanana : public Fruit
{
public:virtual void sayname(){cout<<"South Banana \n"<<endl;}
};//南方苹果
class SouthApple : public Fruit
{
public:virtual void sayname() {cout << "South Apple \n" << endl;}
};//北方香蕉
class NorthBanana : public Fruit
{
public:virtual void sayname(){cout<<"North Banana \n"<<endl;}
};//北方苹果
class NorthApple : public Fruit
{
public:virtual void sayname(){cout<<"North Apple \n"<<endl;}
};class SourthFruitFactory : public FruitFactory
{
public:virtual Fruit* getApple(){return new SouthApple();}virtual Fruit* getBanana(){return new SouthBanana();}
};
class NorthFruitFactory : public FruitFactory
{
public:virtual Fruit* getApple(){return new NorthApple();}virtual Fruit* getBanana(){return new NorthBanana();}
};
int main()
{FruitFactory * ff = NULL;Fruit *fruit = NULL;ff = new SourthFruitFactory(); // 1、建个南方工厂fruit = ff->getApple();        // 2、建立南方苹果fruit->sayname();fruit = ff->getBanana();       // 3、建立南方香蕉fruit->sayname();delete fruit;delete ff;ff = new NorthFruitFactory();fruit = ff->getApple();fruit->sayname();fruit = ff->getBanana();fruit->sayname();delete fruit;delete ff;cout<<"hello....\n";return 0;
}

运行结果

South Apple South Banana North Apple North Banana hello....

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/393287.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GitHub Revert Merge Commit的现象观察和对PR的思考

文章目录 前言Pull Request 为什么会是这样&#xff1f;Pull Request Branch的差异 ?Two Dot Diff和Three Dot Diff 老生常谈&#xff1a; Merge 和 Rebasegit mergegit rebase Revert Main分支中的一个Merge Commit现象描述解决方案: Revert Feature分支中的一个Merge Commi…

Linux系统 腾讯云服务/宝塔面板安装《最新版本2024》禅道开源版本20.2

文章目录 目录 文章目录 安装流程 小结 概要安装流程技术细节小结 概要 有两种方式1.自带有服务器安装和2.使用禅道官方的服务器免费使用 第一种&#xff1a;免费的提供5人使用&#xff0c;存储的数据大小也是有限制的范围的 禅道下载 - 禅道项目管理软件 下滑页面就能…

python中的魔术方法(特殊方法)

文章目录 1. 前言2. __init__方法3. __new__方法4. __call__方法5. __str__方法6. __repr__方法7. __getitem__方法8. __setitem__方法9. __delitem__方法10. __len__方法11. 富比较特殊方法12. __iter__方法和__next__方法13. __getattr__方法、__setattr__方法、__delattr__方…

Linux用户-普通用户

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注我&#xff0c;我尽量把自己会的都分享给大家&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux是一个多用户多任务操作系统,这意味着它可以同时支持多个用户登录并使用系统。…

微信小程序实现上传照片功能

案例&#xff1a; html: <view class"zhengjianCont fontSize30" style"margin-bottom: 40rpx;"><view class"kuai"><image binderror"imageOnloadError" bind:tap"upladPhoto" data-params"business…

杂谈c语言——3.内存对齐

先看两个例子&#xff1a; typedef struct S {int a;double b;char c; }S;typedef struct B {int a;char b;double c; }B;int main() {printf("S : %d\n", sizeof(S));printf("B : %d\n", sizeof(B));return 0; } 结果为&#xff1a; S:24; B:16&#xff…

常用在线 Webshell 查杀工具推荐

一、简介 这篇文章将介绍几款常用的在线 Webshell 查杀工具&#xff0c;包括长亭牧云、微步在线云沙箱、河马和VirusTotal。每个工具都有其独特的特点和优势&#xff0c;用于帮助用户有效检测和清除各类恶意 Webshell&#xff0c;保障网站和服务器的安全。文章将深入探讨它们的…

【Redis】String字符串

目录 String字符串 常见命令 SET GET MSET MGET SETNX 计数命令 INCR INCRBY DECY DECYBY INCRBYFLOAT 其他命令 APPEND GETRANGE SETRANGE STRLEN 内部编码 String类型的典型使用场景 缓存(Cache)功能 计数功能 共享会话(Session) String字符串 字符…

类和对象(下)C++

1.初始化列表 1.为什么有初始化列表&#xff0c;它的作用&#xff1f; ->初始化列表&#xff0c;是构造函数初始化的另一种形式。 ->在语法上面理解&#xff0c;初始化列表可以认定为是每个成员变量定义初始化的地方. ->引用成员变量&#xff0c;const成员变量&am…

Qt实现简易CAD软件的开发:技术解析与实现

文章目录 简易CAD软件的开发&#xff1a;技术解析与实现引言项目概述程序入口主窗口的实现主窗口类定义&#xff08;mainwindow.h&#xff09;主窗口类实现&#xff08;mainwindow.cpp&#xff09; 自定义绘图视图自定义绘图视图类定义&#xff08;myqgraphicsview.h&#xff0…

亚信安全获国家信息安全服务(风险评估和安全工程类)二级资质

近日&#xff0c;亚信安全荣获由中国信息安全测评中心颁发的《国家信息安全测评信息安全服务资质证书—风险评估二级》和《国家信息安全测评信息安全服务资质证书—安全工程类二级》资质。亚信安全凭借综合实力和优秀的技术能力&#xff0c;成为为数不多的获得国家信息安全服务…

嵌入式C编程常用的异常错误处理

嵌入式C编程中&#xff0c;异常错误处理是确保系统稳定性和可靠性的重要部分。以下是一些常见的异常错误处理方法及其详细说明和示例&#xff1a; 1. 断言 (Assertions) 断言用于在开发阶段捕获程序中的逻辑错误。通过assert宏&#xff0c;可以在条件不满足时终止程序并输出错…

前端常用的【设计模式】和使用场景

设计原则 最重要的&#xff1a;开放封闭原则 对扩展开放对修改封闭 工厂模式 用一个工厂函数&#xff0c;来创建实例&#xff0c;隐藏 new 如 jQuery 的 $ 函数&#xff0c;React 的 createElement 函数 单例模式 全局唯一的实例(无法生成第二个) 如 Vuex 和 Redux 的 store…

鸿蒙AI功能开发【人脸活体验证控件】 机器学习-场景化视觉服务

人脸活体验证控件 介绍 本示例展示了使用视觉类AI能力中的人脸活体验证能力。 本示例模拟了在应用里&#xff0c;跳转人脸活体验证控件&#xff0c;获取到验证结果并展示出来。 需要使用hiai引擎框架人脸活体验证接口kit.VisionKit.d.ts。 效果预览 使用说明&#xff1a; …

Web性能监测的利器Performance Observer!!

前言 前段时间在研究前端异常监控平台&#xff0c;在思考性能监控时&#xff0c;想到了浏览器自带的观察者以及页面生命周期API 。于是在翻查资料时发现了&#xff0c;Performance ObserverAPI。正好趁着这个机会给大家好好讲讲Performance Observer API Performance Observe…

【python】Scrapy中常见的“Response Not Ready”或“Response Not 200”错误分析及解决

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

吴恩达机器学习笔记

1.机器学习定义&#xff1a; 机器学习就是让机器从大量的数据集中学习&#xff0c;进而得到一个更加符合现实规律的模型&#xff0c;通过对模型的使用使得机器比以往表现的更好 2.监督学习&#xff1a; 从给定的训练数据集中学习出一个函数&#xff08;模型参数&#xff09;…

【Jenkins未授权访问漏洞 】

默认情况下 Jenkins面板中用户可以选择执行脚本界面来操作一些系统层命令&#xff0c;攻击者可通过未授权访问漏洞或者暴力破解用户密码等进入后台管理服务&#xff0c;通过脚本执行界面从而获取服务器权限。 第一步&#xff1a;使用fofa语句搜索 搜索语句&#xff1a; port&…

【八股文】Redis

1.Redis有哪些数据类型 常用的数据类型&#xff0c;String&#xff0c;List&#xff0c;Set&#xff0c;Hash和ZSet&#xff08;有序&#xff09; String&#xff1a;Session&#xff0c;Token&#xff0c;序列化后的对象存储&#xff0c;BitMap也是用的String类型&#xff0c;…

CCRC-CISAW信息安全保障人员证书含金量

在数字化时代背景下&#xff0c;CISAW认证受到越来越多个人的青睐。 特别是在互联网技术高速发展的今天&#xff0c;随着5G技术的广泛应用&#xff0c;市场对CISAW专业人才的需求急剧增加。 这种职业不仅地位显著&#xff0c;而且职业生涯相对较长。 目前市场上&#xff0c;…