单例模式:

     
 单例模式是一种常用的软件设计模式,它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

单例模式的要求:

* 构造函数私有化
* 增加静态私有类指针变量
* 增加静态公有接口,可以让用户获取单例对象
单例模式基本形式:
class A { private: A(){ a=new A; } public: static A* getInstance(){ return a;
} private: static A* a; } //调用 A* A::a=NULL;
单例模式的分类:

懒汉式:直接创建出类的实例化。

            空间换时间,因为上来就实例化一个对象,占用了内存,并不管主程序是否用到该类。

饿汉式:在需要的时候创建类的实例化。

            时间换空间,与饿汉式相反。

懒汉式代码示例:
/*懒汉式单例模式*/ class Singleton_lazy{ private: /*构造函数私有化,保证不在类的外部实例化*/
Singleton_lazy(){cout<<"我是懒汉式构造函数"<<endl;} public: /*用户接口,在使用的时候创建一个类的实例化*/
static Singleton_lazy* getInstance(){ //判断pSingleton是否为NULL,如果为NULL,即判定需要实例化 if
(pSingleton==NULL){ pSingleton=new Singleton_lazy; } return pSingleton; }
private: static Singleton_lazy* pSingleton; //静态类对象 }; //静态对象类外初始化
Singleton_lazy* Singleton_lazy::pSingleton=NULL;
饿汉式代码示例:
/*饿汉式单例模式*/ class Singleton_hungry{ private:
Singleton_hungry(){cout<<"我是饿汉式构造函数"<<endl;} public: /*返回已经创建好的类实例*/ static
Singleton_hungry* getInstance(){ return pSingleton; } private: static
Singleton_hungry* pSingleton; }; //类外初始化:直接创建出类的实例 Singleton_hungry*
Singleton_hungry::pSingleton=new Singleton_hungry;
对比测试:

在上述懒汉式、饿汉式单例类的基础上进行测试对比:

* 在主函数中,仅仅创建了懒汉式单例类对象,而在代码运行结果中显然存在饿汉式单例类的构造函数调用结果,说明
懒汉式需要在类的外部主动实例化,而饿汉式则在类定义好之后自动实例化。
* 由代码运行结果可知,饿汉式单例类在执行main函数之前就已经实例化调用了构造函数,而懒汉式单例类则是在main函数内部主动实例化时调用构造函数。
int main() { cout<<"main函数开始"<<endl; Singleton_lazy*
p1=Singleton_lazy::getInstance(); return 0; } /*测试代码输出结果*/ 我是饿汉式构造函数 main函数开始
我是懒汉式构造函数
对比与选择:

* 由于要进行线程同步,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现,可以实现更好的性能。这是以空间换时间。
* 在访问量较小时,采用懒汉实现。这是以时间换空间。
单例模式与多线程

懒汉式遇到多线程,不是线程安全的。解决方法:加锁。

饿汉式遇到多线程,是线程安全的。 由于在多线程启动前已经创建好类实例对象,不会重新实例化,是线程安全的。

线程安全的懒汉式单例类:
/*线程安全的懒汉式单例类*/ class Singleton_lazy{ protected: Singleton_lazy() {
pthread_mutex_init(&mutex,NULL); } public: static Singleton_lazy*
getInstance(); static pthread_mutex_t mutex; private: static Singleton_lazy*
pSingleton; }; pthread_mutex_t Singleton_lazy::mutex; Singleton_lazy*
Singleton_lazy::pSingleton=NULL; Singleton_lazy*Singleton_lazy::getInstance() {
if (pSingleton==NULL) { pthread_mutex_lock(&mutex); if(pSingleton==NULL)
pSingleton=new Singleton_lazy; pthread_mutex_unlock(&mutex); } return
pSingleton; }
 

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信