一、用模板实现单例模式
在前面的文章中,用过多种方法实现单例模式,现在用模板方式来实现:
为了实现线程安全,需要在linux 下使用pthread_mutex_t 加锁,请使用g++ 编译并需要链接 -lpthread
使用的是double-check lock, 指针instance_ 最好声明为volatile,防止优化。
Singleton.h:
/*************************************************************************
????>?File?Name:?Singleton.h
????>?Author:?Simba
????>?Mail:?dameng34@163.com
????>?Created?Time:?Wed?02?Apr?2014?01:33:39?AM?PDT
?************************************************************************/
#ifndef?_SINGLETON_H_
#define?_SINGLETON_H_
#include?<iostream>
#include?<stdlib.h>
#include?<pthread.h>
#include?<unistd.h>
#include?<sys/types.h>
#include?<stdio.h>
#include?<errno.h>
#include?<string.h>
using?namespace?std;
template?<?typename?T?>?class?Singleton
{
public:
????static?T?&GetInstance()
????{
????????Init();
????????return?*instance_;
????}
private:
????static?void?Init()
????{
????????if?(instance_?==?0)
????????{
????????????pthread_mutex_lock(&g_mutex);
????????????if?(instance_?==?0)
????????????{
????????????????instance_?=?new?T;
????????????????atexit(Destroy);????//程序结束时调用注册的函数
????????????}
????????????pthread_mutex_unlock(&g_mutex);
????????}
????}
????static?void?Destroy()
????{
????????delete?instance_;
????}
????Singleton(const?Singleton?&other);
????Singleton?&operator=(const?Singleton?&other);
????Singleton();
????~Singleton();
????static?T?*?volatile?instance_;
????static?pthread_mutex_t?g_mutex;
};
template?<?typename?T?>
T?*?volatile?Singleton?<?T?>::instance_?=?0;
template?<?typename?T?>
pthread_mutex_t?Singleton<T>?::g_mutex?=?PTHREAD_MUTEX_INITIALIZER;
#endif??????????????//?_SINGLETON_H_
main.cpp:
/*************************************************************************
????>?File?Name:?main.cpp
????>?Author:?Simba
????>?Mail:?dameng34@163.com
????>?Created?Time:?Wed?02?Apr?2014?01:30:13?AM?PDT
?************************************************************************/
#include?"Singleton.h"
class?ApplicationImpl
{
public:
????ApplicationImpl()
????{
????????cout?<<?"ApplicationImpl?..."?<<?endl;
????}
????~ApplicationImpl()
????{
????????cout?<<?"~ApplicationImpl?..."?<<?endl;
????}
????void?Run()
????{
????????cout?<<?"Run?..."?<<?endl;
????}
};
typedef?Singleton?<?ApplicationImpl?>?Application;
void?*routine(void?*arg)
{
????Application::GetInstance().Run();
}
int?main(void)
{
????Application::GetInstance().Run();
????pthread_t?tid;
????int?ret;
????if?((ret?=?pthread_create(&tid,?NULL,?routine,?NULL))?!=?0)
????{
????????fprintf(stderr,?"pthread?create:?%s\n",?strerror(ret));
????????exit(EXIT_FAILURE);
????}
????Application::GetInstance().Run();
????pthread_join(tid,?NULL);
????return?0;
}
即 将Singleton 实现为模板类,将ApplicationImpl 类包装成单例模式类,可以看到构造函数和析构函数都只调用了一次。程序使用一个小技巧,用axexit 函数注册了程序结束时需要调用的函数。
二、模板方式实现动态创建对象
在前面的文章曾经使用宏定义的方式实现动态创建对象,现在在 DynBase.h 中用模板类将宏定义替换掉,其他代码不变:
//class?Register
//{
//public:
//????Register(const?string?&name,?CREATE_FUNC?func)
//????{
//????????DynObjectFactory::Register(name,?func);
//????}
//};
//
//#define?REGISTER_CLASS(class_name)?\
//class?class_name##Register?{?\
//public:?\
//????static?void*?NewInstance()?\
//????{?\
//????????return?new?class_name;?\
//????}?\
//private:?\
//????static?Register?reg_;?\
//};?\
//Register?class_name##Register::reg_(#class_name,?class_name##Register::NewInstance)
template?<typename?T>
class?DelegatingClass
{
public:
????DelegatingClass(const?string?&name)
????{
????????DynObjectFactory::Register(name,?&(DelegatingClass::NewInstance));
????}
????static?void?*NewInstance()
????{
????????return?new?T;
????}
};
#define?REGISTER_CLASS(class_name)?DelegatingClass<class_name>?class##class_name(#class_name)
即?REGISTER_CLASS(class_name)?宏定义展开会构造一个模板类实例对象,调用3次宏定义即3个模板类实例对象,调用构造函数
DelegatingClass(const?string?&name),进而调用Register 完成注册,接下去的流程与以前的程序一样,不再赘述。输出如下:
参考:
C++ primer 第四版 Effective C++ 3rd C++编程规范