前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从零开始学C++之模板(四):用模板实现单例模式(线程安全)、模板方式实现动态创建对象

从零开始学C++之模板(四):用模板实现单例模式(线程安全)、模板方式实现动态创建对象

作者头像
s1mba
发布2017-12-25 20:02:23
1.7K0
发布2017-12-25 20:02:23
举报
文章被收录于专栏:开发与安全开发与安全

一、用模板实现单例模式

前面的文章中,用过多种方法实现单例模式,现在用模板方式来实现:

为了实现线程安全,需要在linux 下使用pthread_mutex_t 加锁,请使用g++ 编译并需要链接 -lpthread

使用的是double-check lock, 指针instance_ 最好声明为volatile,防止优化。

Singleton.h:

代码语言:cpp
复制
/*************************************************************************
????>?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:

代码语言: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 中用模板类将宏定义替换掉,其他代码不变:

代码语言:cpp
复制
//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++编程规范

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2013-07-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com