什么是 Single Instance 单例模式?
单例模式是计算机程序设计当中一种常用思路,即软件系统运行当中,该类只允许拥有一个实例,且它必须在初始化的时候自己创建自己的实例。
那么单例模式主要是什么用途呢?
优化访问性能,便于进行数据共享。
比如说:
1,软件系统运行当中,业务上的配置文件参数共享。
2,多线程之间数据的共享。
3,调用类似于数据库操作这种需要频繁访问的对象时,减少 Object 的频繁创建销毁和函数调用的栈内存消耗。
4,数据需要临时保存时,给其他对象提供一个统一化的数据接口。
5,提升高度复用情况下的访问性能。
那么单例模式的具体实现方式是?
创建一个类,这个类会自己创建自己在内存当中的实例,实例可以被其他类访问,同时不允许以任何方式再次创建这个类的实例。
其中有什么原则?
1,必须保证在整个软件系统运行的生命周期当中,实例仅有一个,不能被再次创建,也不能被拷贝、赋值。
2,必须保证内存的安全性问题。
3,必须保证线程的安全性问题。
4,必须保证实例仅能通过指定的接口获得。
那么具体有什么细节?
1,可以通过将 构造、拷贝构造、赋值运算符重载 声明为 Private 以保证实例不会被再次创建。
2,可以通过智能指针进行包装,以保证内存的安全性。
3,可以通过使用 Static 关键字保证实例指针常驻于内存全局变量区。
4,可以使用 std::call_once 来保证类的实例只会创建一次,并且不会有线程安全问题。
单例模式分为主动模式和被动模式,区别是:
主动模式在类加载时就已经创建好了自己的实例。
被动模式在被第一次调用时才会创建自己的实例。
这里演示的是被动模式:
================== 创建一个叫大脑工具箱的“工类” ==================
----------------- 头文件 -----------------
usingstd::shared_ptr; usingstd::make_shared; usingstd::call_once; usingstd::once_flag; // 创建一个叫大脑工具箱的单例类classBrainToolBox{ public: // 获取单例的函数staticshared_ptr<BrainToolBox>GetInstance(); public: // 供调用的测试函数voidHelloByte(); private: // Private 锁死构造和析构BrainToolBox(); ~BrainToolBox(); // Private 锁死拷贝构造BrainToolBox(constBrainToolBox&) {}; // Private 锁死赋值运算符BrainToolBox&operator=(constBrainToolBox&) {}; private: // 单例的指针声明staticshared_ptr<BrainToolBox>BrainInstance; // Onec Flag 声明staticonce_flagBrainOnceFlag; };
----------------- CPP文件 -----------------
// 单例的指针定义shared_ptr<BrainToolBox>BrainToolBox::BrainInstance; // OnceFlag 定义once_flagBrainToolBox::BrainOnceFlag; // 获取单例 如果不存在则创建且只创建一次shared_ptr<BrainToolBox>BrainToolBox::GetInstance() { call_once(BrainToolBox::BrainOnceFlag, [&] { structmake_shared_enabler : BrainToolBox{}; BrainToolBox::BrainInstance=make_shared<make_shared_enabler>(); }); returnBrainToolBox::BrainInstance; } // 测试输出一段字符串以确定单例类被成功创建voidBrainToolBox::HelloByte() { std::cout<<"Hello Byte!"<<std::endl; return; } // 构造BrainToolBox::BrainToolBox() { } // 析构BrainToolBox::~BrainToolBox() { }
================== 测试一下 ==================
intmain() { shared_ptr<BrainToolBox>tool=BrainToolBox::GetInstance(); tool->HelloByte(); }
会打印 Hello Byte 字符串。
====================================
芯片烤电池 C++ Example 2022-Spring Season Pass :
【Example】C++ 回调函数及 std::function 与 std::bind
【Example】C++ 标准库智能指针 unique_ptr 与 shared_ptr
【Example】C++ Template (模板)概念讲解及编译避坑
【Example】C++ 标准库 std::thread 与 std::mutex
【Example】C++ 标准库多线程同步及数据共享 (std::future 与 std::promise)
【Example】C++ 标准库 std::condition_variable
【Example】C++ 用于编译时封装的 Pimpl 演示 (编译防火墙 Private-IMPL)
【Example】C++ 单例模式 演示代码 (被动模式、兼容VS2022编译)
====================================