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

C++ 常用设计模式

1、单例模式

一个类只有一个实例,提供一个全局访问点来访问这个实例。
分为懒汉模式和饿汉模式:

  • 懒汉模式就是 只有用到这个实例才会初始化对象并返回 (调用了对外的接口才实例化对象)
  • 饿汉模式就是 不管用不用得到,都先构造出来,先初始化

双重锁的懒汉模式:

#include <mutex>class SingeLazy {
private:SingeLazy() {}SingeLazy(const SingleLazy& ) = delete;SingeLazy& operator= (const SingleLazy& ) = delete;static SingleLazy* instance;static mutex i_mutex;public:static SingleLazy* getInstance() {if (instance == nullptr) {mutex.lock();if (instance == nullptr) {instance = new SingleLazy();}mutex.unlock();}return instance;
}
};
SingleLazy* SingleLazy::instance = nullptr;
mutex SingleLazy::i_mutex; // 类外初始化

双重锁机制(Double-Checked Locking)用于确保单例对象只被创建一次,并且提高线程安全性和性能。

为什么要进行第二次检查 if (instance == nullptr)
当第一个线程获得锁并创建单例对象时,其他等待的线程可能已经通过了第一次检查 if (instance == nullptr),并准备进入加锁阶段。如果没有第二次检查,当第一个线程释放锁之后,第二个线程会获得锁并尝试再次创建对象。

场景描述:

  • 线程A进入 getInstance(),通过了第一次检查,发现 instance == nullptr,然后加锁并创建实例。
  • 线程B几乎同时进入 getInstance(),也通过了第一次检查,因为当时 instance 还没被创建,但它被阻塞在锁等待状态。
  • 当线程A创建了实例并释放锁,线程B获得锁,并进入锁定区域。如果没有第二次检查,线程B会认为 instance 仍然是
    nullptr,并再次尝试创建实例。

因此,第二次检查的作用是防止在第一个线程创建实例后,其他线程重复创建实例

2、非拷贝模式与父子类继承

/*
派生类在调用构造函数和析构函数时会首先调用基类的构造函数和析构函数noncopyable 被继承后 派生类对象可以正常调用 构造函数 和 析构函数
但是派生类对象无法使用拷贝构造函数 和 赋值操作
*/
class noncopyable
{
public:noncopyable(const noncopyable&) = delete; // 拷贝noncopyable& operator=(const noncopyable&) = delete; // 赋值protected:noncopyable() = default;~noncopyable() = default;
};class Channel : noncopyable 
{...
};

在这里插入图片描述
这种模式常见的应用场景包括:

  1. 资源管理类(如文件、线程、内存管理类):禁止拷贝,防止多个对象持有相同的资源句柄。
  2. 单例模式(Singleton):单例对象通常不允许被拷贝和赋值,以确保应用中只有一个实例存在。
  3. 智能指针类(如 std::unique_ptr):独占所有权的智能指针类禁止拷贝,以确保资源只由一个对象管理。

除了这个之外,还需要注意一个知识点:
如果基类是 class(如 noncopyable),则默认继承权限为 私有继承
如果基类是 struct,则默认继承权限为 公有继承

所以 noncopyable 类中的 public 和 protect 成员都在 Channel 类中变为 private 成员,只允许类内调用,不允许 Channel 所创建对象调用。
有关继承的权限问题:
1、public继承:父类public在子类继承为public,protected在子类中继承为protected,private不被继承(这也是protected和private的区别);
2、public继承:父类public和protected在子类中都继承为protected;
3、private继承:父类public和protected在子类中都继承为private。


http://www.mrgr.cn/news/31045.html

相关文章:

  • MySQL技巧之跨服务器数据查询:基础篇-动态参数
  • jmeter基础05_第1个http请求
  • JavaScript:loadScript 方法
  • Android OpenGL ES详解——纹理:纹理过滤GL_NEAREST和GL_LINEAR的区别
  • 项目管理-招标文书都有哪些文件且各自作用
  • B3997 [洛谷 202406GESP 模拟 三级] 小洛的字符串分割
  • 小朋友分组最少调整次数
  • 102. 二叉树的层序遍历
  • git入门进阶
  • Elasticsearch:检索增强生成背后的重要思想
  • C++ Primer Plus(速记版)-面向对象与泛型编程
  • 【qt】一个WPS项目了解qt界面设计的基本套路
  • 大模型日报|7 篇必读的大模型论文
  • 【永磁同步电机(PMSM)】 2. 数学模型
  • 虚拟机ens33网卡不显示inet地址(已设置NOBOOT为yes)
  • 基于Java的题库管理系统设计与实现(springboot vue)
  • 如何将3D模型嵌入正在Web网页?支持什么模型格式?
  • sql基础语法及常见函数等
  • Linux —— 多线程
  • 广东深圳地区的数据与应用集成系统推荐
  • 【AI大模型-提示词中的###和“““】
  • 文献阅读(81)FACT
  • 什么是CSRF攻击,该如何防护CSRF攻击
  • visionpro脚本
  • MySQL 数据库备份与恢复指南
  • 使用反向代理软件frp在局域网内共享上网