设计模式之单例模式实现(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 ...
随机推荐
- 随手记录-linux-常用命令
转自:https://www.cnblogs.com/yjd_hycf_space/p/7730690.html linux目录结构:http://www.cnblogs.com/fat39/p/72 ...
- ./configure的含义
在实践安装nginx的时候,不知道./configure是什么意思,这里特地记录一下. 在linux中./代表当前目录,属于相对路径../代表上一级目录,属于相对路径/代表根目录,/开头的文件都是绝对 ...
- mysql和oracle查询出的一条结果中的多个字段拼接
1,mysql concat('a','b','c')和concat_ws('a','b','c')的区别:前者如果有某个值为空,结果为空;后者如果有某个值为空,可以忽略这个控制 SELECT con ...
- Dailu Scrum (2015/10/27)
在周日晚上PM已经为大家分配了部分的代码修改工作,今天晚上PM召集了被分配代码工作的3个DEV一起讨论要求修改的代码.在共同讨论的过程中确有发现以下代码的不规范之处,PM当即要求我们先要修改规范代码的 ...
- Java 单生产者消费者问题
package com.cwcec.test; class Resource { private int count = 0; private boolean flag = false; public ...
- NBA篮球足球在线直播插件下载
PPlive:点此下载PPLive播放器 Sopcast:点此下载Sopcast播放器 UUSee:点此下载UUSee播放器 CCTVReg:点此下载CCTV插件 PPStream:点此下载PPstr ...
- GC 年轻代 老年代 持久代
转载自:http://www.cnblogs.com/yaoyuan23/p/5587548.html 虚拟机中的共划分为三个代:年轻代(Young Generation).老年代(Old Gener ...
- .NET项目中常用的32个正则表达式总结
最近没事总结了下最近所用到的正则表达式,下面32个是经常用到的,总结下来与大家分享. . "^-?[1-9]\\d*$",//整数 . "^[1-9]\\d*$" ...
- Unity3d学习日记(六)
今天在研究怎么在unity中将image上的图片保存到本地,主要参考下面两个链接:Unity Texture2D缩放.UNITY存储图片到本地 结合上述两个链接,我写了如下代码来将缩放后或者改 ...
- IE盒模型与W3C盒模型区别
前两天被人问到,叫我解释一下标准盒模型与IE盒模型,额,当时只能说,知道一点,但是没有深入的去探讨过,所以下来之后就自己写了例子,亲自去验证并且查看了网上的一些资料,现将其整理如下: 一.css盒模型 ...