设计模式之单例模式实现(C++)
#ifndef SINGLETON_H
#define SINGLETON_H #include <cassert>
#include <memory>
#include <mutex> #define DECLARE_SINGLETON_CLASS(T) friend Singleton<T> template <typename T>
class Singleton
{
public:
using PT = std::shared_ptr<T>; Singleton() = delete;
~Singleton() = delete; public:
template <typename... Args>
static PT getInstance(Args&&... args)
{
// std::call_once(m_flag, create, std::forward<Args>(args)...);
// error: no matching function for call call_once... <unresolved overloaded function type>
// couldn't deduce template parameter '_Callable'
// why ?
std::call_once(m_flag, [&]() {
create(std::forward<Args>(args)...);
});
assert(m_instance);
return m_instance;
} private:
template <typename... Args>
static void create(Args&&... args)
{
m_instance = std::shared_ptr<T>{new T(std::forward<Args>(args)...), destroy};
} static void destroy(T* t)
{
delete t;
} private:
static std::once_flag m_flag;
static PT m_instance;
}; template <typename T>
std::once_flag Singleton<T>::m_flag; template <typename T>
typename Singleton<T>::PT Singleton<T>::m_instance{}; #endif // SINGLETON_H
#include "Singleton.h"
#include <iostream>
#include <string> using namespace std; #define print() cout << "[" << __func__ << ":" << __LINE__ << "]"
#define print_position() print() << endl
#define print_class() print() << " " << typeid(*this).name() << " " #if 1 class Bundle
{
public:
Bundle()
{
print_class() << "construct" << endl;
} ~Bundle()
{
print_class() << "destruct" << endl;
} Bundle(const Bundle& )
{
print_class() << "copy construct" << endl;
} Bundle(Bundle&&)
{
print_class() << "move construct" << endl;
} Bundle& operator=(Bundle&)
{
print_class() << "copy operator assign" << endl;
return *this;
} Bundle& operator=(Bundle&&)
{
print_class() << "move operator assign" << endl;
return *this;
}
}; class SingleInstanceKlass
{
DECLARE_SINGLETON_CLASS(SingleInstanceKlass); private:
SingleInstanceKlass()
{
print_class() << "default construct" << endl;
}
SingleInstanceKlass(int)
{
print_class() << "int construct" << endl;
}
SingleInstanceKlass(const string&)
{
print_class() << "string construct" << endl;
}
SingleInstanceKlass(const Bundle&)
{
print_class() << "Bundle construct" << endl;
}
~SingleInstanceKlass()
{
print_class() << "destruct" << endl;
} public:
void run()
{
print_position();
}
}; template <typename... Args>
void unused(Args...)
{
} void onExit()
{
print_position();
} int main(int argc, char *argv[])
{
unused(argc, argv); atexit(onExit); print_position();
{
Singleton<SingleInstanceKlass>::getInstance(Bundle{});
Singleton<SingleInstanceKlass>::getInstance(.);
Singleton<SingleInstanceKlass>::getInstance();
Singleton<SingleInstanceKlass>::getInstance("")->run();
}
print_position(); return ;
} #endif
设计模式之单例模式实现(C++)的更多相关文章
- 设计模式之单例模式(Singleton)
设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...
- GJM : C#设计模式(1)——单例模式
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...
- java设计模式之单例模式(几种写法及比较)
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
- 每天一个设计模式-4 单例模式(Singleton)
每天一个设计模式-4 单例模式(Singleton) 1.实际生活的例子 有一天,你的自行车的某个螺丝钉松了,修车铺离你家比较远,而附近的五金店有卖扳手:因此,你决定去五金店买一个扳手,自己把螺丝钉固 ...
- 设计模式之单例模式的简单demo
/* * 设计模式之单例模式的简单demo */ class Single { /* * 创建一个本类对象. * 和get/set方法思想一样,类不能直接调用对象 * 所以用private限制权限 * ...
- 设计模式之单例模式——Singleton
设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...
- 10月27日PHP加载类、设计模式(单例模式和工厂模式)、面向对象的六大原则
加载类可以使用include.require.require_once三种中的任意一种,每个关键字都有两种方法,但是这种方法的缺点是需要加载多少个php文件,就要写多少个加载类的方法.一般也就需要加载 ...
- java 23 - 2 设计模式之单例模式
单例模式:保证类在内存中只有一个对象. 如何保证类在内存中只有一个对象呢? A:把构造方法私有 B:在成员位置自己创建一个对象 C:通过一个公共的方法提供访问 单例模式之饿汉式: (一进来就造对 ...
- [转]JAVA设计模式之单例模式
原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主 ...
- python_way,day8 面向对象【多态、成员--字段 方法 属性、成员修饰符、特殊成员、异常处理、设计模式之单例模式、模块:isinstance、issubclass】
python_way day8 一.面向对象三大特性: 多态 二.面向对象中的成员 字段.方法属性 三.成员修饰符 四.特殊成员 __init__.__doc__.__call__.__setitem ...
随机推荐
- 升级Xcode 10 后报错问题记录([CP] Copy Pods Resources)
1.升级Xcode到Version 10.0 (10A255)后,运行已有项目,报如下错误: error: Multiple commands produce '/Users/galahad/Libr ...
- (第七周)评论alpha发布
本人所在组:奋斗吧兄弟 按课上展示组的顺序对其他组进行点评: 1. 新蜂 项目:游戏俄罗斯方块 界面完善,已经实现了游戏的基本功能.可以对图形进行变换形状,进行位置移动,可以加快下落的速度,并对一整 ...
- Scrum Meeting 6 -2014.11.12
今天apec最后一天,大部分任务都差不多了,局部测试问题不大.大家修复下小细节就可以开始整合了. Member Today’s task Next task 林豪森 协助测试及服务器部署 协助测试及服 ...
- Daily Scrum (2015/10/29)
今天晚上我们学霸项目的三个小组在一起开会,讨论如何能在后期使我们三个项目更好地结合在一起.为了三个小组的能够同时工作,不出现某一小组因需要其他小组成果而停滞的情况,我们决定围绕lucene,solr, ...
- 软件团队项目第一次Sprint评价(评价人:张家军)
组号 组名 缺点及建议 1 理财猫 (1)没有附带的计算器 (2)支入支出没有详细菜单说明 (3)界面背景单调 ...
- Chapter 11 软件演化
软件一直在不断地演化发展,人们通常通过软件维护和软件再工程解决软件的缺陷.软件维护可以分为改正性维护.适应性维护和完善性维护几种类型.软件维护受开发过程影响大.软件维护困难大.软件维护成本高.软件维护 ...
- c#学习路线及目录导航
一 很久前的想法 转眼间,2018年已经过了四分之一,从我进入学校选择计算机专业到现在工作,已经过去了4年之久了.这一路走来经历了很多的曲折,对软件开发这个职业有了许多新的认识,我主要是从事NET领域 ...
- 【CSAPP笔记】9. 汇编语言——缓冲区溢出
x86-64 Linux 内存结构 先来看看一个程序在内存中是如何组织的.Linux 为每个进程维持了一段单独的虚拟地址空间.(进程是计算机科学中很深刻.很成功的一个概念.当我们在运行一个程序时,会得 ...
- APP案例分析-热血江湖
本次分析的是一款游戏名叫热血江湖,这是我上小学的时候就在玩的游戏,可以说是一直玩到现在所以对它有一定的感情,所以决定分析这款游戏.下面附一张现在的游戏登陆界面. 第一部分 调研, 评测 1.下载软件并 ...
- visual stdio2013软件安装及单元测试
visual stdio2013软件安装及单元测试 一.visual stdio2013软件安装详解 今天,笔者为大家带来如何在Windows10下完美安装Visual Studio 2013专业版. ...