C++:特殊类的设计 | 单例模式

目录

1、特殊类的设计

2、设计一个类,不能被拷贝

3、设计一个类,只能在堆上创建对象

4、设计一个类,只能在栈上创建对象

5、设计一个类,不能被继承

6、单例模式

1、饿汉模式

2、懒汉模式


1、特殊类的设计

        在实际应用场景中,会存在一些特殊类的设计,比如:

设计一个只能在堆上创建对象的类,这样的设计可以用于需要动态管理内存,或者需要确保对象生命周期与程序控制流无关的场景中。

设计一个不能被拷贝的类,这样的设计常用于需要禁止对象被复制的场景,例如单例模式、线程池等。

 在实际场景中,还有其他的特殊类设计,下面我们来列举几个。

2、设计一个类,不能被拷贝

如果让一个类不拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可

在C++98中,将拷贝构造函数与赋值运算符重载只声明不定义,并且将其访问权限设置为私有即可。

class CopyBan
{
public:CopyBan(){}private:CopyBan(const CopyBan&);CopyBan& operator=(const CopyBan&);//...
};int main()
{CopyBan c;//CopyBan s(c);//CopyBan s=c;return 0;
}

   

而在C++11中,拓展了delete的用法,delete除了释放new申请的资源外,如果在默认成员函数后跟上=delete,表示让编译器删除掉该默认成员函数。

class CopyBan
{
public:CopyBan(){}CopyBan(const CopyBan&) = delete;CopyBan& operator=(const CopyBan&) = delete;//...
};
int main()
{CopyBan c;//CopyBan s(c);//CopyBan s=c;return 0;
}

3、设计一个类,只能在堆上创建对象

只能在对上创建对象,那么只能使用new来创建

1、私有化析构函数

这样在栈上创建对象会报错

2、可以使用私有的构造函数和析构函数,并通过静态成员函数返回堆上分配的对象指针。这样可以确保对象只能通过堆上的分配方式创建,而不能在栈上创建。


class HeapOnly {
private:// 私有构造函数和析构函数,防止在栈上创建对象HeapOnly() {}~HeapOnly() {}public:// 静态成员函数用于返回堆上分配的对象指针static HeapOnly* createObject() {return new HeapOnly();}
};int main()
{HeapOnly* h = HeapOnly::createObject();//HeapOnly s;  return 0;
}

为防止通过拷贝构造在栈上创建对象,需要禁用拷贝构造和赋值重载。

 // 声明拷贝构造函数和赋值运算符重载为私有,不实现它们HeapOnly(const HeapOnly&);HeapOnly& operator=(const HeapOnly&);

也可以使用C++11中的delete关键字。

4、设计一个类,只能在栈上创建对象

1、同上将构造函数私有化,然后设计静态方法创建对象返回即可
class StackOnly
{
public:static StackOnly CreateObj(){return StackOnly();}// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉// StackOnly obj = StackOnly::CreateObj();// StackOnly* ptr3 = new StackOnly(obj);void* operator new(size_t size) = delete;void operator delete(void* p) = delete;
private:StackOnly()  :_a(0){}
private:int _a;
};

5、设计一个类,不能被继承

1、在C++98中可以将构造函数私有化派生类中调不到基类的构造函数。则无法继承

// C++98中构造函数私有化,派生类中调不到基类的构造函数。则无法继承
class NonInherit
{
public:static NonInherit GetInstance(){return NonInherit();}
private:NonInherit(){}
};

2、在C++11中使用final 关键字

 final关键字,final修饰类,表示该类不能被继承。

class A  final
{// ....
};

6、单例模式

单例模式是一种设计模式,用于确保类只有一个实例,并提供一个全局访问点。这在需要全局访问点且只需一个实例的情况下非常有用。

在单例模式中,类通常会提供一个静态成员函数来获取类的唯一实例,并且将构造函数设置为私有,以防止直接实例化类的对象。如果类的实例尚未创建,则静态成员函数会创建一个实例并返回它,否则会返回已存在的实例。

一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个 访问它的全局访问点,该实例被所有程序模块共享

1、饿汉模式

不管你将来用不用,程序启动时就创建一个唯一的实例对象。
// 饿汉模式
// 优点:简单
// 缺点:可能会导致进程启动慢,且如果有多个单例类对象实例启动顺序不确定。
class Singleton
{
public:static Singleton* GetInstance(){return &m_instance;}
private:// 构造函数私有Singleton() {};// C++98 防拷贝Singleton(Singleton const&);Singleton& operator=(Singleton const&);// or// C++11Singleton(Singleton const&) = delete;Singleton& operator=(Singleton const&) = delete;static Singleton m_instance;
};
Singleton  Singleton::m_instance;
如果这个单例对象在多线程高并发环境下频繁使用,性能要求较高,那么显然使用饿汉模式来避
免资源竞争,提高响应速度更好。
饿汉模式是单例模式的一种变体,它在类加载时就创建了实例,而不是在需要时才创建。这种方式的优点是简单直接,线程安全,但可能会带来性能开销,因为实例在程序启动时就会被创建。

2、懒汉模式

懒汉模式是单例模式的另一种变体,它在需要时才创建实例,而不是在类加载时就创建。这种方式的优点是节省了内存,因为实例只在需要时才被创建,但需要考虑线程安全性。

#include <mutex>class Singleton {
private:// 静态成员变量,用于保存唯一实例static Singleton* instance;// 私有构造函数,防止外部实例化对象Singleton() {}// 互斥锁,用于保证线程安全static std::mutex mutex;public:// 静态成员函数,返回类的唯一实例static Singleton* getInstance() {// 在多线程环境下确保只有一个线程能够创建实例std::lock_guard<std::mutex> lock(mutex);// 如果实例尚未创建,则创建一个新实例if (!instance) {instance = new Singleton();}return instance;}
};// 在类外初始化静态成员变量
Singleton* Singleton::instance = nullptr;
// 初始化互斥锁
std::mutex Singleton::mutex;

在这个实现中,通过互斥锁确保了在多线程环境下的线程安全性。在调用Singleton::getInstance() 时,如果实例尚未创建,则会创建一个新实例并返回,否则会直接返回已存在的实例。

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

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

相关文章

系统镜像地址

系统镜像 Linux 官网下载地址&#xff1a;Downloadhttps://www.centos.org/download/ 阿里云镜像下载地址&#xff1a;https://mirrors.aliyun.com/centos/https://mirrors.aliyun.com/centos/?spma2c6h.13651104.d-2001.6.6554320cwFqB8E 清华大学镜像下载地址&#xff1…

SCI一区 | WOA-BiTCN-BiGRU-Attention多输入单输出回归预测(Matlab)

SCI一区 | WOA-BiTCN-BiGRU-Attention多输入单输出回归预测&#xff08;Matlab&#xff09; 目录 SCI一区 | WOA-BiTCN-BiGRU-Attention多输入单输出回归预测&#xff08;Matlab&#xff09;效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现WOA-BiTCN-BiGRU-A…

【C++】学习笔记——list

文章目录 八、list1. list的介绍2. list的使用3. list的模拟实现4. list模拟实现的代码整合1. list.h2. test.cpp 未完待续 八、list list链接 1. list的介绍 是的&#xff0c; list 就是带头双向循环链表。 2. list的使用 通过 string 和 vector 的学习&#xff0c;我们差…

基于TL431和CSA的恒压与负压输出

Hello uu们,51去那里玩了呀?该收心回来上班了,嘿嘿! 为什么会有这个命题,因为我的手头只有这些东西如何去实现呢?让我们一起来看电路图吧.电路图如下图1所示 图1:CSA恒压输出电路 图1中,R1给U2提供偏置,Q1给R1提供电流,当U1-VOUT输出大于2.5V时候,U2内部的三极管CE导通,使得…

第四百九十二回

文章目录 1. 概念介绍2. 使用方法2.1 SegmentedButton2.2 ButtonSegment 3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"SearchBar组件"相关的内容&#xff0c;本章回中将介绍SegmentedButton组件.闲话休提&#xff0c;让我们一起Talk …

Qt扫盲-Qt D-Bus概述

Qt D-Bus概述 一、概述二、总线三、相关概念1. 消息2. 服务名称3. 对象的路径4. 接口5. 备忘单 四、调试五、使用Qt D-Bus 适配器1. 在 D-Bus 适配器中声明槽函数1. 异步槽2. 只输入槽3. 输入输出槽4. 自动回复5. 延迟回复 一、概述 D-Bus是一种进程间通信(IPC)和远程过程调用…

分布式与一致性协议之ZAB协议(四)

ZAB协议 ZooKeeper是如何选举领导者的。 首先我们来看看ZooKeeper是如何实现成员身份的&#xff1f; 在ZooKeeper中&#xff0c;成员状态是在QuorumPeer.java中实现的&#xff0c;为枚举型变量 public enum ServerState { LOOKING, FOLLOWING, LEADING, OBSERVING }其实&…

【JAVA入门】Day03 - 数组

【JAVA入门】Day03 - 数组 文章目录 【JAVA入门】Day03 - 数组一、数组的概念二、数组的定义2.1 数组的静态初始化2.2 数组的地址值2.3 数组元素的访问2.4 数组遍历2.5 数组的动态初始化2.6 数组的常见操作2.7 数组的内存分配2.7.1 Java内存分配2.7.2 数组的内存图 一、数组的概…

【数据结构】--- 深入剖析二叉树(中篇)--- 认识堆堆排序Topk

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; 数据结构之旅 文章目录 &#x1f3e0; 初识堆 &#x1f4d2; 堆的概念 &#x1f4d2; 堆的性质 &#x1f3e0; 向上调整算法 && 向下调整算…

【云原生】Pod 的生命周期(一)

【云原生】Pod 的生命周期&#xff08;一&#xff09;【云原生】Pod 的生命周期&#xff08;二&#xff09; Pod 的生命周期&#xff08;一&#xff09; 1.Pod 生命期2.Pod 阶段3.容器状态3.1 Waiting &#xff08;等待&#xff09;3.2 Running&#xff08;运行中&#xff09;3…

《Python编程从入门到实践》day20

#尝试在python3.11文件夹和pycharm中site-packages文件夹中安装&#xff0c;最终在scripts文件夹中新建py文件成功导入pygame运行程序 #今日知识点学习 import sysimport pygameclass AlienInvasion:"""管理游戏资源和行为的类"""def __init__(…

memory consistency

memory consistency model 定义了对于programmer和implementor来说&#xff0c;访问shared memory system的行为&#xff1b; 对于programmer而言&#xff0c;他知道期望值是什么&#xff0c; 知道会返回什么样的数据&#xff1b;&#xff1b; 对于implementro而言&#xff0c;…

微信小程序原生代码实现小鱼早晚安打卡小程序

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 小鱼早晚安打卡小程序&#xff1a;开启健康生活&#xff0c;共享正能量 在这个快节奏的时代&#xff0c;我们常常被各种琐事和压力所困扰&#xff0c;以至于忽略了对健康生活方式的追求。然…

【探秘地球宝藏】矿产资源知多少?

当我们仰望高楼林立的城市&#xff0c;乘坐便捷的交通工具&#xff0c;享受各种现代生活的便利时&#xff0c;你是否曾想过这一切背后的支撑力量&#xff1f;答案就藏在我们脚下——矿产资源&#xff0c;这些大自然赋予的宝贵财富&#xff0c;正是现代社会发展的基石。今天&…

OpenHarmony 实战开发——ABI

OpenHarmony系统支持丰富的设备形态&#xff0c;支持多种架构指令集&#xff0c;支持多种操作系统内核&#xff1b;为了应用在各种OpenHarmony设备上的兼容性&#xff0c;本文定义了"OHOS" ABI&#xff08;Application Binary Interface&#xff09;的基础标准&#…

idea中取消自动导包顺序

1、取消自动导入 2、取消导包顺序设置

Python学习笔记------处理数据和生成折线图

给定数据&#xff1a; jsonp_1629344292311_69436({"status":0,"msg":"success","data":[{"name":"美国","trend":{"updateDate":["2.22","2.23","2.24",&qu…

奶爸预备 |《P.E.T.父母效能训练:让亲子沟通如此高效而简单:21世纪版》 / 托马斯·戈登——读书笔记

目录 引出致中国读者译序前言第1章 父母总是被指责&#xff0c;而非受训练第2章 父母是人&#xff0c;不是神第3章 如何听&#xff0c;孩子才会说&#xff1a;接纳性语言第4章 让积极倾听发挥作用第5章 如何倾听不会说话的婴幼儿第6章 如何听&#xff0c;孩子才肯听第8章 通过改…

保研面试408复习 3——操作系统

文章目录 1、操作系统一、进程有哪几种状态&#xff0c;状态之间的转换、二、调度策略a.处理机调度分为三级&#xff1a;b.调度算法 标记文字记忆&#xff0c;加粗文字注意&#xff0c;普通文字理解。 为什么越写越少&#xff1f; 问就是在打瓦。(bushi) 1、操作系统 一、进程…

设计模式Java实现-建造者模式

楔子 小七在2019年的时候&#xff0c;就想写一个关于设计模式的专栏&#xff0c;但是最终却半途而废了。粗略一想&#xff0c;如果做完一件事要100分钟&#xff0c;小七用3分钟热情做的事&#xff0c;最少也能完成10件事情了。所以这一次&#xff0c;一定要把他做完&#xff0…