Revolver源码解析之——单例模式

1、基本概念。

在整个程序运行期间只需要某个类的一个实例化对象,在程序结束运行时,销毁这个类对应的对象。

2、单线程安全的版本。

【实现】

#ifndef __BASE_SIGNLETON_H
#define __BASE_SIGNLETON_H

#include <stdlib.h>
#include "base_os.h"

template<class T>
class CSingleton
{
public:
	static T* instance()
	{
#if defined(__linux__) || defined(__APPLE__)
		pthread_once(&ponce_, &CSingleton::init);
#else
        if(obj_ == NULL)
			obj_ = new T();
#endif

		return obj_;
    }

	static void destroy()
	{
		if(obj_ != NULL)
		{
			delete obj_;
			obj_ = NULL;
		}
    }

protected:
	CSingleton()
	{
    }

	virtual ~CSingleton()
	{
    }

protected:
#ifndef WIN32
	static pthread_once_t ponce_;
#endif

	static T*	obj_;

private:
	CSingleton(const CSingleton&)
	{
    }

	CSingleton& operator=(const CSingleton&)
	{
    }

	static void init()
	{
		obj_ = new T();
    }
};

#if defined(__linux__) || defined(__APPLE__)
template <class T> pthread_once_t CSingleton<T>::ponce_ = PTHREAD_ONCE_INIT;
#endif

template <class T> T* CSingleton<T>::obj_ = NULL;

#endif


要点:

1>定义一个静态的成员对象变量,将这个类的构造函数、析构函数设置为protected,并将这个类的复制构造函数与赋值运算符函数设置为private,以保证类外不可见。

2>提供统一的对外接口instance()成员函数来返回这个类的唯一的全局的对象指针。windows平台下,第一次new出来一个对象指针并返回之,而后直接返回这个对象指针;linux平台下第一个调用pthread_once()来初始化全局的对象指针,而后直接返回全局的对象指针。

3>【类外】需要对静态的全局对象指针进行初始化。

3、线程安全的单例模式版本(muduo的版本)。

因为muduo没有考虑跨平台,因此,只考虑了如何在linux环境下实现线程安全的单例模式。

实现

简化版本:

template<typename T>
class Singleton:boost::noncopyable
{
public:
    static T& instance()
    {
        pthread_once(&ponce_,&Singleton::init);
        return *value_;
    }

private:

    Singleton();
    ~Singleton();

    static void init()
    {
        value_=new T();
    }

private:
    static pthread_once_t ponce_;
    static T* value_;

};

template<typename T>
pthread_once_t Singleton<T>::ponce_=PTHREAD_ONCE_INIT;
T* Singleton<T>::value_=nullptr;

要点:

1>将构造函数、析构函数均设置为private,禁止外界访问,即禁止构造与析构;

2>将一个静态的对象指针作为类的私有成员变量。申明一个静态的成员变量ponce_;

3>提供一个对外的接口instance()来提供全局的T类型的对象指针的访问。

4>类外初始化两个静态数据成员。





猜你喜欢

转载自blog.csdn.net/weixin_40825228/article/details/80965049