用模板实现单例模式(线程安全)、模板方式实现动态创建对象
一、用模板实现单例模式
在前面的文章中,用过多种方法实现单例模式,现在用模板方式来实现:
为了实现线程安全,需要在linux 下使用pthread_mutex_t 加锁,请使用g++ 编译并需要链接 -lpthread
使用的是double-check lock, 指针instance_ 最好声明为volatile,防止优化。
Singleton.h:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
/*************************************************************************
> File Name: Singleton.h > Author: Simba > Mail: dameng34@163.com > Created Time: Wed 02 Apr 2014 01:33:39 AM PDT ************************************************************************/ #ifndef _SINGLETON_H_ #include <iostream> using namespace std; template < typename T > class Singleton public: private: pthread_mutex_lock(&g_mutex); static void Destroy() Singleton(const Singleton &other); static T * volatile instance_; template < typename T > template < typename T > #endif // _SINGLETON_H_ |
main.cpp:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
/*************************************************************************
> 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() void Run() typedef Singleton < ApplicationImpl > Application; void *routine(void *arg) int main(void) pthread_t tid; Application::GetInstance().Run(); pthread_join(tid, NULL); return 0; |
即 将Singleton 实现为模板类,将ApplicationImpl 类包装成单例模式类,可以看到构造函数和析构函数都只调用了一次。程序使用一个小技巧,用axexit 函数注册了程序结束时需要调用的函数。
二、模板方式实现动态创建对象
在前面的文章曾经使用宏定义的方式实现动态创建对象,现在在 DynBase.h 中用模板类将宏定义替换掉,其他代码不变:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
//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> static void *NewInstance() #define REGISTER_CLASS(class_name) DelegatingClass<class_name> class##class_name(#class_name) |
即 REGISTER_CLASS(class_name) 宏定义展开会构造一个模板类实例对象,调用3次宏定义即3个模板类实例对象,调用构造函数
const string &name),进而调用Register 完成注册,接下去的流程与以前的程序一样,不再赘述。输出如下:
参考:
C++ primer 第四版
Effective C++ 3rd
C++编程规范
转载于:https://www.cnblogs.com/alantu2018/p/8471404.html
用模板实现单例模式(线程安全)、模板方式实现动态创建对象相关推荐
- C++11线程库模板
推荐一个非常好的C++11的线程库模板:https://github.com/progschj/ThreadPool/blob/master/ThreadPool.h 包含了C++11的特性,重点学习 ...
- 走进AngularJs(二) ng模板中常用指令的使用方式
通过使用模板,我们可以把model和controller中的数据组装起来呈现给浏览器,还可以通过数据绑定,实时更新视图,让我们的页面变成动态的.ng的模板真是让我爱不释手.学习ng道路还很漫长,从模板 ...
- 项目案例模板之jdbc两种连接方式
项目案例模板之jdbc两种连接方式 第一种连接方式 JDBCUtils.java package jdbc;import org.junit.jupiter.api.Test;import jav ...
- Java实现根据Word模板填充表格数据(poi方式),以及doc和docx转PDF,最全最详细版本,解决外部引用jar在linux上报ClassNotFound的问题。
Java实现根据Word模板填充表格数据(poi方式),以及doc和docx转PDF,最全最详细版本,解决外部引用jar在linux上报ClassNotFound的问题. 适用场景: 1.固定格式的W ...
- poi模板操作word两种实现方式
目录 1.手动创建模板 1.1 jar包导入 1.2 Excel工具编写 1.3 创建模板 1.4 调用模板生成接口 1.5 重写 WordExportUtil.exportWord07(templa ...
- 模板代码复用的三种方式: 宏, 继承, 包含
模板代码复用 在模板中,可能会遇到以下情况: 多个模板具有完全相同的顶部和底部内容 多个模板中具有相同的模板代码内容,但是内容中部分值不一样 多个模板中具有完全相同的 html 代码块内容 宏 对宏( ...
- html pdf 模板,记一次 HTML 模板 转 PDF
HTM模板的样式和实际转pdf样式会有非常大的差距 获取模板的方式也是十分曲折... 这里记录一下便捷的方式 第一步: 在前端调用windows的打印页面 这里的样式完全和html一一致:左侧 目标打 ...
- php模板引擎如何实现,php模板引擎技术简单实现
用了smarty,tp过后,也想了解了解其模板技术是怎么实现,于是写一个简单的模板类,大致就是读取模板文件->替换模板文件的内容->保存或者静态化 tpl.class.php主要解析 as ...
- 提高开发效率之安卓模板(上面有四种模板的教程,我之前会两种,看完之后还是只会两种2333)
原文地址: juejin.im/post/5c7339- 在平时的开发工作中,我们经常将一个地方的代码,复制粘贴到另外一个地方,俗称搬砖,搬砖搬多了,作为一个资深的挨踢民工,难免会总结一些提高生产力的 ...
最新文章
- 【视频】【zt】温馨的求婚
- docker命令大全
- Why Spring Boot
- 终极解码播放mkv声音小的解决
- 手机充满电不拔有什么影响吗?
- Android Multimedia框架总结(九)Stagefright框架之数据处理及到OMXCodec过程
- @@HOW TO:检查 MDAC 版本
- “易升”升级Win10卡在99%的处理办法
- 收藏+下载!Flink 社区 2021 最新最全学习渠道汇总
- pcl小知识(十二)—— 斯坦福兔子和其他图形学模型数据下载
- Linux中的Cat命令–如何使用Cat或Touch创建文本文件
- 南昌大学计算机学硕和专硕,专硕和学硕哪个好?该怎么选?
- 老马 Markov 其人
- 聊聊程序员与英语,程序员不学英语行吗?
- 从零开始入门 K8s | Kubernetes API 编程利器:Operator 和 Operat
- 关于腾讯云服务器的域名备案流程(尽力图文并茂)
- 李宏毅HW01——新冠疫情数据的预测
- 吴裕雄--天生自然 诗经:游子吟
- 深度神经网络的理解和实践例子,很好。
- 蓝牙之二十-设备类型
热门文章
- python的flask框架显示柱状图_使用Python的Flask框架,结合Highchart,动态渲染图表(Ajax 请求数据接口)...
- js 多个定时器_从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理(二)
- mingle_大众汽车品牌SUV之夜,数千平米的mingle区和超长弧面屏了解一下?
- Redis初学17:集群
- 【蓝桥java】递归基础之39级台阶
- 小程序云开发,判断数据库表的两个字段匹配 云开发数据库匹配之 and 和 or 的配合使用
- dispatch callback ant design pro 网络请求回调函数
- 083、Prometheus架构(2019-05-05 周日)
- 大数据推荐(个性化推荐)
- C#图片灰度处理(位深度24→位深度8),用灰度数组byte[]新建一个8位灰度图像Bitmap 。...