C++实现单例模式




提示:以下是本篇文章正文内容,下面案例可供参考

一、单例模式是什么?

无论怎么获取,永远只能得到该类类型的唯一一个实例对象。
注意下面三个点:

  1. 构造函数需私有化
    将该类的构造函数私有化,目的是禁止其他程序创建该类的对象,同时也是为了提醒查看代码的人我这里是在使用单例模式,防止他人将这里任意修改。此时,需要提供一个可访问类自定义对象的类成员方法(对外提供该对象的访问方式)。

  2. 指向本身实例的类属性为静态
    指向自己实例的私有引用在被类方法(Getinstance)调用时被初始化,只有静态成员变量才能在没有创建对象时进行初始化,并且类的静态成员在第一次使用时不会再被初始化,保证了单例,因此设置为静态。

  3. 通过一个static静态成员方法返回唯一的对象实例
    通过类方法(GetInstance) 获取instance,类属性instance为静态的(static),则需要类的静态方法才能调用,因此该类方法应设为静态的。

二、程序

1.饿汉单例模式

饿汉式单例模式,顾名思义,就是程序启动时就实例化了该对象,并没有推迟到第一次使用该对象时再进行实例化;如果运行过程中没有使用到,该实例对象就被浪费掉了。

class CSingleton {
public:
    static CSingleton* getInstance() {
        return &single;
    }

private:
    static CSingleton single;
    CSingleton();
    ~CSingleton();
    CSingleton(const CSingleton&){}

};
CSingleton CSingleton::single;

2.懒汉单例模式

懒汉式单例模式,顾名思义,就是对象的实例化,延迟到第一次使用它的时候。

class CSingleton {
public:
    static CSingleton* getInstance() {
        if (single == nullptr) {
            single = new CSingleton();
        }
        return single;
    }

private:
    static CSingleton* single;
    CSingleton();
    ~CSingleton();
    CSingleton(const CSingleton&){}

    //注意如果没有下面的释放资源类,在main函数中将手动释放资源
    class CRelease {
    public:
        ~CRelease() { delete single; }
    };
    static CRelease release;

};
CSingleton* CSingleton::single = nullptr;
CSingleton::CRelease CSingleton::release;

3.线程安全单例模式

考虑在多线程下的情景

3.1 饿汉单例模式的线程安全特性
饿汉单例模式中,单例对象定义成了一个static静态对象,它是在程序启动时,main函数运行之前就初始化好的,因此不存在线程安全问题,可以放心的在多线程环境中使用。

3.2 饿汉单例模式的线程安全特性
getInstance是个不可重入函数,也就它在多线程环境中执行,会出现竞态条件问题。因此需要考虑加锁

class CSingleton
{
public:
	static CSingleton* getInstance()
	{
		// 获取互斥锁
		pthread_mutex_lock(&mutex);
		if (nullptr == single)
		{
			single = new CSingleton();
		}
		// 释放互斥锁
		pthread_mutex_unlock(&mutex);
		return single;
	}
private:
	static CSingleton *single;
	CSingleton() 
	~CSingleton() 
	{ 
		pthread_mutex_destroy(&mutex); // 释放锁
	}
	CSingleton(const CSingleton&);

	class CRelease
	{
	public:
		~CRelease() { delete single; }
	};
	static CRelease release;
	
	// 定义线程间的互斥锁
	static pthread_mutex_t mutex;
};
CSingleton* CSingleton::single = nullptr;
CSingleton::CRelease CSingleton::release;
// 互斥锁的初始化
pthread_mutex_t CSingleton::mutex = PTHREAD_MUTEX_INITIALIZER;

Logo

科技之力与好奇之心,共建有温度的智能世界

更多推荐