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>类外初始化两个静态数据成员。