创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c++系列专栏:C/C++零基础到精通 🔥
给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ
c语言内容💖:
专栏:c语言之路重点知识整合
目录
单例模式
单例模式确保了一个类只有一个实例,并提供一个全局访问点来获取这个实例。
单例模式的特点:
- 1.一个类只有一个实例
- 2.提供一个全局访问点来获取这个实例
- 3.单例对象必须由单例类进行创建(构造函数设为私有 private)
如何实现单例模式?
构造析构拷贝构造私有
提供静态公有的获取对象的方法
饿汉式单例模式
在类刚开始加载的时候就创建好对象,不会出现线程安全问题
cpp
#include <iostream>
using namespace std;
class Singleton
{
private:
// 静态成员变量在类声明时就已经初始化
static Singleton* sin;
// 私有构造函数,确保外部无法直接创建实例
Singleton(){}
Singleton(const Singleton& single) = delete; // 使用delete替代私有构造函数
// 析构函数也设置为私有,但这在饿汉式单例中不是必需的,因为对象是在程序结束时自动销毁的
~Singleton(){}
public:
static Singleton* getSingle()
{
// 直接返回已经初始化的静态对象的地址
return sin;
}
void fun()
{
cout << "Singleton::fun()" << endl;
}
};
// 在类外初始化静态成员变量
Singleton* Singleton::sin = new Singleton();
int main()
{
//获取单例对象
Singleton* single1 = Singleton::getSingle();
single1->fun();
getchar();
return 0;
}
在类被加载时就被初始化为一个指向新创建的Singleton对象的指针。
因此,无论何时调用Singleton::getSingle(),它都会返回同一个对象的地址。
在程序结束时,这个静态的Singleton对象会被自动销毁
懒汉式单例模式
类加载时没有生成单例,而是在第一次调用获取实例的方法时才去创建这个单例。 会出现线程安全问题,即当多个线程同时访问某个对象或数据时,可能导致数据的不一致或错误
cpp
#include <iostream>
using namespace std;
class Singleton
{
private:
static Singleton* sin;
Singleton(){}
Singleton(const Singleton& single) = delete; // 使用delete替代私有构造函数
~Singleton(){}
public:
static Singleton* getSingle()
{
if (sin == nullptr) // 如果单例对象还未被创建
{
sin = new Singleton(); // 创建单例对象
}
return sin;
}
void fun()
{
cout << "Singleton::fun()" << endl;
}
};
Singleton* Singleton::sin = nullptr;
int main()
{
//获取单例对象
Singleton* single1 = Singleton::getSingle();
single1->fun();
getchar();
return 0;
}
单例模式的优缺点
优点
- 控制资源访问 :通过单例模式,可以确保对某个资源的全局访问点只有一个,这样可以防止其他对象对该资源的访问导致状态不一致或数据污染。
- 减少系统开销 :如果一个类的实例创建非常消耗资源(如读取配置文件、打开数据库连接等),使用单例模式可以确保系统只创建一个实例,从而减少系统开销。
- 简化配置 :在单例模式中,由于类的实例是预先创建好的,因此在系统启动时就可以加载和初始化,这样可以简化配置和初始化工作。
- 便于管理 :由于单例模式提供了全局访问点,因此可以很方便地对实例进行管理和维护。
- 避免对象之间的直接耦合 :使用单例模式可以避免对象之间的直接耦合,而是通过单例类来协调它们之间的关系。
缺点
- 在多线程下,懒汉式单例模式可能会引起线程安全问题
- 由于单例模式的本质是将类的实例化控制权交由类本身来管理,因此难以扩展。如果需要为单例类添加新的功能,可能需要修改原有的代码,这可能会违反开闭原则
- 单例模式可能会将多个功能放在同一个类中,这可能会违反单一职责原则
应用示例
在使用 mysql 对象操作某个数据库中中,通常只使用一个 mysql 对象,对数据库进行复用连接,而不是为每个请求都创建一个新的连接
GetInstance 方法是获取单例实例的公共静态方法,使用 std::call_once 来确保线程安全地初始化单例实例
cpp
#include <mysql.h>
#include <string.h>
#include <iostream>
#include <list>
#include <mutex>
using namespace std;
class CMySql
{
private:
CMySql() {} // 私有构造函数,防止外部使用 new 关键字创建实例
CMySql(const CMySql&) = delete; // 删除拷贝构造函数
CMySql& operator=(const CMySql&) = delete; // 删除赋值运算符
public:
static CMySql& GetInstance()
{
std::call_once(initInstanceFlag, &InitSingleton);
return *m_pInstance;
}
public:
~CMySql(void);
bool ConnectMySql(const char* host, const char* user, const char* pass, const char* db, short nport = 3306);
void DisConnect();
bool SelectMySql(char* szSql, int nColumn, list<string>& lstStr);
bool GetTables(char* szSql, list<string>& lstStr);
bool UpdateMySql(char* szSql);
private:
static CMySql* m_pInstance; // 静态私有成员变量,保存类的唯一实例
static std::once_flag initInstanceFlag; // 用于确保线程安全的初始化
MYSQL* m_sock;
MYSQL_RES* m_results;
MYSQL_ROW m_record;
// 初始化单例的函数
static void InitSingleton()
{
m_pInstance = new CMySql();
}
};
// 初始化静态成员变量
CMySql* CMySql::m_pInstance = nullptr;
std::once_flag CMySql::initInstanceFlag;
// 析构函数
CMySql::~CMySql()
{
// 清理资源等操作
}
|--------------------------------------|
| 大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。 |
|---------------------------------------------------------------|
| 大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●) |