一个类只有一个实例化对象
全局可以使用
单例模式的基本实现:包含单例模式的实现,线程安全,以及生命周期等
单例模式的模板实现, 多模块调用单例存在的问题
单例模式的基本实现
私有的构造函数, 拷贝构造函数,以及
operator=
, 保证其不能够在类的外部进程对象构造,拷贝等操作。GetInstance
是一个公有的静态成员函数,用来构造这个类唯一的实例对象m_objConfig
, 并且返回给使用者。
class SingletonConfig
{
public:
static SingletonConfig * GetInstance()
{
if (m_objConfig = = nullptr)
m_objConfig = new SingletonConfig;
return m_objConfig;
}
private:
SingletonConfig() { ; };
SingletonConfig(const SingletonConfig&) { ; };
SingletonConfig& operator= (const SingletonConfig&) { ; };
private:
static SingletonConfig *m_objConfig;
};
SingletonConfig* SingletonConfig::m_objConfig = nullptr;
复制
单例模式生命周期
单例创建的时机
class SingletonConfig
{
public:
static SingletonConfig * GetInstance()
{
return m_objConfig;
}
private:
SingletonConfig() { ; };
SingletonConfig(const SingletonConfig&) { ; };
SingletonConfig& operator= (const SingletonConfig&) { ; };
private:
static SingletonConfig *m_objConfig;
};
SingletonConfig* SingletonConfig::m_objConfig = new SingletonConfig;
复制
单例释放的时机
class SingletonConfig
{
public:
static SingletonConfig * GetInstance()
{
static SingletonConfig objConfig;
return &objConfig;
}
virtual ~SingletonConfig()
{
std::cout << "~SingletonConfig()" << std::endl;
}
private:
SingletonConfig() { ; };
SingletonConfig(const SingletonConfig&) { ; };
SingletonConfig& operator= (const SingletonConfig&) { ; };
};
复制
class SingletonConfig
{
public:
static SingletonConfig * GetInstance()
{
if (m_objConfig == nullptr)
m_objConfig = new SingletonConfig;
return m_objConfig;
}
static void ReleaseInstance()
{
if (m_objConfig)
{
delete m_objConfig;
m_objConfig = nullptr;
}
}
virtual ~SingletonConfig()
{
std::cout << "~SingletonConfig()" << std::endl;
}
private:
SingletonConfig() { ; };
SingletonConfig(const SingletonConfig&) { ; };
SingletonConfig& operator= (const SingletonConfig&) { ; };
private:
static SingletonConfig* m_objConfig;
};
SingletonConfig* SingletonConfig::m_objConfig = nullptr;
复制
线程安全
static SingletonConfig * GetInstance()
{
static SingletonConfig objConfig;
return &objConfig;
}
复制
static SingletonConfig * GetInstance()
{
if (m_objConfig == nullptr)
m_objConfig = new SingletonConfig;
return m_objConfig;
}
复制
使用
std::lock_guard
去多线程保证互斥双重的
m_objConfig == nullptr
检查,第一次是为了效率,当单例对象已经在的时候,就不需要互斥锁了;第二次是进入锁范围之后,要查看下,是否有其他线程已经创建了单例对象,如果还没有创建才进行创建。
class SingletonConfig
{
public:
static SingletonConfig * GetInstance()
{
if (m_objConfig == nullptr)
{
std::lock_guard<std::mutex> guard(m_mutex);
if (m_objConfig == nullptr)
{
m_objConfig = new SingletonConfig;
}
}
return m_objConfig;
}
static void ReleaseInstance()
{
if (m_objConfig)
{
delete m_objConfig;
m_objConfig = nullptr;
}
}
virtual ~SingletonConfig()
{
std::cout << "~SingletonConfig()" << std::endl;
}
private:
SingletonConfig() { ; };
SingletonConfig(const SingletonConfig&) { ; };
SingletonConfig& operator= (const SingletonConfig&) { ; };
private:
static SingletonConfig* m_objConfig;
static std::mutex m_mutex;
};
SingletonConfig* SingletonConfig::m_objConfig = nullptr;
std::mutex SingletonConfig::m_mutex;
复制
单例模式的模板实现以及可能的问题
template<typename T>
class CommonSingleton
{
public:
static T* GetInstance()
{
if (m_objSingle == nullptr)
{
std::lock_guard<std::mutex> guard(m_mutex);
if (m_objSingle == nullptr)
{
m_objSingle = new T;
}
}
return m_objSingle;
}
static void ReleaseInstance()
{
if (m_objSingle)
{
delete m_objSingle;
m_objSingle = nullptr;
}
}
private:
CommonSingleton() { ; };
CommonSingleton(const CommonSingleton&) { ; };
CommonSingleton& operator= (const CommonSingleton&) { ; };
private:
static T* m_objSingle;
static std::mutex m_mutex;
};
template<typename T>
T* CommonSingleton<T>::m_objSingle = nullptr;
template<typename T>
std::mutex CommonSingleton<T>::m_mutex;
复制
CommonSingleton<TestClass>::GetInstance();
复制
模板参数接受的类,可以是这种:默认暴露给用户,可以构造,拷贝,赋值的类,这样便可以重新创造多个对象。这种方式缺乏了本人所理解的
防御性
编程的思路。当使用模板实例化的时候,同一种模板参数的类,在多个不同的模块中其实都会有自己的实例化对象。比如有A和B两个模块,并且均调用了
CommonSingleton<TestClass>::GetInstance();
, 其实在A和B中存在不同的TestClass
对象,这样也违背了一个程序一个实例化对象的初衷。当然只有一个工程不影响。对于非模板的实现,一般将单例实现的类从模块导出,将实现放在.cpp
文件中,那么这种多个工程对同一种单例的类只会有一个实例化对象。个人觉得这一点比较重要,需要读者多多体会。
总结
参考
<<C++设计新思维>>
中的Singletons实作技术这一章节<<深入应用C++11代码优化及工程级应用>>
的改进单例模式这一章节
文章转载自一个程序员的修炼之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
【专家观点】罗敏:从理论到真实SQL,感受DeepSeek如何做性能优化
墨天轮编辑部
1251次阅读
2025-03-06 16:45:38
【专家有话说第五期】在不同年龄段,DBA应该怎样规划自己的职业发展?
墨天轮编辑部
1244次阅读
2025-03-13 11:40:53
2025年2月国产数据库大事记
墨天轮编辑部
971次阅读
2025-03-05 12:27:34
2025年2月国产数据库中标情况一览:GoldenDB 3500+万!达梦近千万!
通讯员
861次阅读
2025-03-06 11:40:20
2月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
444次阅读
2025-03-13 14:38:19
AI的优化能力,取决于你问问题的能力!
潇湘秦
412次阅读
2025-03-11 11:18:22
优炫数据库成功应用于国家电投集团青海海南州新能源电厂!
优炫软件
337次阅读
2025-03-21 10:34:08
达梦数据与法本信息签署战略合作协议
达梦数据
286次阅读
2025-03-06 09:26:57
国产化+性能王炸!这套国产方案让 3.5T 数据 5 小时“无感搬家”
YMatrix
270次阅读
2025-03-13 09:51:26
磐维数据库对外门户全新升级!
磐维数据库
237次阅读
2025-03-04 15:32:59