C++ 单例模式
时间:2022-07-26
本文章向大家介绍C++ 单例模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
有两种模式:
懒汉模式:第一次使用的时候才初始化,需要手动实现线程安全。
恶汉模式:程序一开始就初始化,这个可以自动实现线程安全。
原理都是:把构造函数设置为私有,添加一个私有的静态成员指针变量,添加一个public getInstance方法获取指针来使用。
比较常遇到的问题,就是,使用普通指针的话,需要人为的delete,不过如果这个单例对象,需要执行到程序结束的话,也可以由操作系统回收内存。不过这样的话,虽然内存是回收了,但是析构函数是没有执行的,如果你的析构函数里面需要执行一些io操作什么的,那就泡汤了,这个时候,可以引入一个智能指针,这样,在程序结束的最末,会自动析构。目前,自己写一个日志类(使用缓存)就遇到了需要这个的情况。
遇到的问题是,智能指针的初始化,他不能使用类的私有成员,所以要把那个智能指针设置为友元对象。
懒汉模式,线程安全.
CMyThreadPool * CMyThreadPool::getInstance()
{
if( NULL == m_pool){
//lock();
std::lock_guard<std::mutex> l(*singal_mutex);
if( NULL == m_pool){
m_pool = new CMyThreadPool();
}
//unlock();
}
return m_pool;
}
class CMyThreadPool
{
private:
...
public:
~CMyThreadPool(void);
static CMyThreadPool * getInstance();
...
private:
CMyThreadPool(void);
...
static CMyThreadPool * m_pool;
...
};
恶汉模式下,采用普通指针和只能指针.
#include <iostream>
#include <memory>
using namespace std;
class SingletonStatic
{
private:
static const SingletonStatic* m_instance;
static shared_ptr<SingletonStatic> n_instance;
SingletonStatic(){
cout << "hello sig"<<endl;
}
public:
//声明友元对象
friend shared_ptr<SingletonStatic>;
~SingletonStatic(){
cout << "good bye" << endl;
}
static const SingletonStatic* getInstance()
{
return m_instance;
}
static const shared_ptr<SingletonStatic> getNewInstance(){
return n_instance;
}
};
//外部初始化 before invoke main
const SingletonStatic* SingletonStatic::m_instance = new SingletonStatic();
//这里就可以调用他的私有构造函数了
shared_ptr<SingletonStatic> SingletonStatic::n_instance(new SingletonStatic);
int main(){
//需要手动析构普通指针。
delete SingletonStatic::getInstance();
system("pause");
}
- 源码分享:仿余额宝数字跳动效果 TextCounter
- 一键清理应用数据或者清除应用缓存的方法
- 开发者必知:谷歌做了一个艰难的决定
- React编程思想
- 基于 React + Webpack 的音乐相册项目(下)
- Python中Keras深度学习库的回归教程
- Apache Spark 1.1中的统计功能
- 一次关闭所有Activity和连续点击两次返回键关闭程序的方法
- 解决TextView排版混乱或者自动换行的问题
- 怎样设置EditText内部文字被锁定不可删除和修改,而文字只能在后面输入
- 教你如何使用微信网页版“抓取”微信撤回消息
- 移动开发之实现图片轮播效果
- 浅谈Andorid开发中的MVP模式
- jsp标准标签库整理(JSTL)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- redis学习(十)
- vue修改浏览器的标题title
- 天天基金网数据接口
- Centos7实现开机自启EasySwoole
- input内文字与光标的初始位置调整
- 小程序push、unshift、concat
- mac下导出chrome插件及安装
- Job 资源对象
- ReplicaSet && DaemonSet 资源对象
- 批量执行crontab指定条目的注释和解注释
- Rancher集群部署后需要做的几件事
- Ingress(Nginx)日志持久化与可视化(多图预警)
- .Net在Windows上使用Jenkins做CI/CD的那些事
- 【STM32H7】第9章 RL-TCPnet调试方法(Event Recorder和串口两种)
- 【STM32F429】第9章 RL-TCPnet调试方法(Event Recorder和串口两种)