常用设计模式之单例模式

单例模式 (C++)

单例模式应该是很多项目里面经常会被使用到的一个设计模式,这里对单例模式的特点和写法做下介绍。

特点及应用

1. 特点

(1)故名思意,整个程序只会用到这么一个单例对象

举个例子:学校类比成一段程序,学校里面有一位校长对象,校长姓陈,校长今天被通知去教育局开会,明天要去教学生数学,后天要去小李老师课上听课,这三个事情就好比成三个方法,陈校长这个对象会在这三个方法中去做对应的事情,这个过程中一直都是陈校长在做,而不是李校长,王校长,张校长其他校长。

(2)需要通过一个全局访问方法来的得到这个单一实例

举个例子:还是以陈校长为例,陈校长是一个非常朴素的人,他没有手机,电脑等通讯工具,你只能通过去陈校长办公室这个方法来通知校长。

(3)懒汉单例和饿汉单例

懒汉单例:

这个类只有在第一次调用的时候才会被实例化对象。

饿汉单例:

这个类在程序启动或类被加载的时候,创建这个单例对象。

(4)构造函数为私有函数

以C++为例,构造函数的访问权限要求是Private

2. 解决了什么问题

避免一个全局使用的类对象频繁的创建和销毁,以及只使用仅有的这个单例对象,例如一些全局配置类。

3. 懒汉和饿汉的选择

如果一个单例类实例频繁被使用,建议使用饿汉,例如全局配置类,你需要频繁通过这个类去设置和取一些属性的时候;当一个单例类实例比较少被用到,甚至可能程序运行时,都不被用到的,选择懒汉。

写法介绍

懒汉单例

  • 这个是C++11后出现的写法,这里的写法有两种,构造函数私有属性或者是构造函数共有属性删除
// 构造函数私有
class singleton
{
public:
	static singleton* getInstance()
	{
		static singleton instance;
		return &instance;
	}
	~singleton(){}

private:
	singleton(){}
	singleton(const singleton &value){}
	singleton(singleton &&value){}
	singleton &operator=(const singleton &value){}
	singleton &operator=(singleton &&value){}
};
// 构造函数公有删除
class singleton
{
public:
	static singleton* getInstance()
	{
		static singleton instance;
		return &instance;
	}
	singleton(const singleton&) = delete;
	singleton(singleton&&) = delete;
	singleton& operator=(const singleton&) = delete;
	singleton& operator=(singleton&&) = delete;
	~singleton(){}

private:
	singleton() = default;
};
  • C++11前写法,使用互斥锁保证线程安全
// 构造锁类
#include <pthread.h>
class myLocker
{
public:
	myLocker()
	{
		// 初始化互斥锁
		if(pthread_mutex_init(&m_mutex, NULL) != 0)
		{
			throw std::exception();
		}
	}
	~myLocker()
	{
		// 销毁互斥锁,释放内存
		pthread_mutex_destroy(&m_mutex);
	}
	bool lock()
	{
		return pthread_mutex_lock(&m_mutex) == 0;
	}
	bool unlock()
	{
		return pthread_mutex_unlock(&m_mutex) == 0;
	}
private:
	pthread_mutex_t m_mutex;
};
class singleton
{
public:
	static singleton* getInstance()
	{
		if (m_instance == NULL)	// 解决并发问题,是否第一次调用
		{
			locker.lock();
			if (m_instance == NULL)	// 解决多线程时只能拥有一个单例问题
			{
				m_instance = new singleton();
			}
			locker.unlock();
		}
		return m_instance;
	}
private:
	singleton(){}
	singleton(const singleton &value){}
	singleton(singleton &&value){}
	singleton& operator=(const singleton &value){}
	singleton& operator=(singleton &&value){}

	static singleton* m_instance;
	myLocker locker;
};
singleton *singleton::m_instance = NULL;
myLocker singleton::locker;

懒汉单例

  • 懒汉单例就简单多了
class singleton
{
public:
	static singleton *getInstance()
	{
		return &instance;
	}

private:
	static singleton instance;
	singleton() {}
	singleton(const singleton &) = delete;
	singleton &operator=(const singleton &) = delete;
	singleton(singleton &&) = delete;
	singleton &operator=(singleton &&) = delete;
};
singleton singleton::instance; // 类外初始化
posted @ 2022-10-10 00:04  喝碗糖水  阅读(19)  评论(0编辑  收藏  举报