我会写关于c++11的一个系列的文章,会讲到如何使用c++11改进我们的程序,本次讲如何改进我们的模式,会讲到如何改进单例模式、观察者模式、访问者模式、工厂模式、命令模式等模式。通过c++11的改进,我们的模式变得更通用、更简洁、更强大。本次讲如何改进单例模式。

在c++11之前,我们写单例模式的时候会遇到一个问题,就是多种类型的单例可能需要创建多个类型的单例,主要是因为创建单例对象的构造函数无法统一,各个类型的形参不尽相同,导致我们不容易做一个所有类型都通用的单例。现在c+11帮助我们解决了这个问题,解决这个问题靠的是c++11的可变模板参数。直接看代码。

template <typename T>
class Singleton
{
public:
template<typename... Args>
  static T* Instance(Args&&... args)
  {

if(m_pInstance==nullptr)

m_pInstance = new T(std::forward<Args>(args)...);

return m_pInstance;

}

  static T* GetInstance()
  {
    if (m_pInstance == nullptr)
      throw std::logic_error("the instance is not init, please initialize the instance first");

    return m_pInstance;
  }

static void DestroyInstance()
{
delete m_pInstance;
m_pInstance = nullptr;
} private:
Singleton(void);
virtual ~Singleton(void);
Singleton(const Singleton&);
Singleton& operator = (const Singleton&);
private:
static T* m_pInstance;
}; template <class T> T* Singleton<T>::m_pInstance = nullptr;

这个单例模式可以解决不同类型构造函数形参不尽相同的问题,真正意义上对所有类型都通用的单例模式。

/***********更新说明****************/

由于原来的接口中,单例对象的初始化和取值都是一个接口,可能会遭到误用,更新之后,讲初始化和取值分为两个接口,单例的用法为:先初始化,后面取值,如果中途销毁单例的话,需要重新取值。如果没有初始化就取值则会抛出一个异常。

增加Multiton的实现

#include <map>
#include <string>
#include <memory>
using namespace std; template < typename T, typename K = string>
class Multiton
{
public:
template<typename... Args>
static std::shared_ptr<T> Instance(const K& key, Args&&... args)
{
return GetInstance(key, std::forward<Args>(args)...);
} template<typename... Args>
static std::shared_ptr<T> Instance(K&& key, Args&&... args)
{
return GetInstance(key, std::forward<Args>(args)...);
}
private:
template<typename Key, typename... Args>
static std::shared_ptr<T> GetInstance(Key&& key, Args&&...args)
{
std::shared_ptr<T> instance = nullptr;
auto it = m_map.find(key);
if (it == m_map.end())
{
instance = std::make_shared<T>(std::forward<Args>(args)...);
m_map.emplace(key, instance);
}
else
{
instance = it->second;
} return instance;
} private:
Multiton(void);
virtual ~Multiton(void);
Multiton(const Multiton&);
Multiton& operator = (const Multiton&);
private:
static map<K, std::shared_ptr<T>> m_map;
}; template <typename T, typename K>
map<K, std::shared_ptr<T>> Multiton<T, K>::m_map;

c++11 boost技术交流群:296561497,欢迎大家来交流技术。

(原创)c++11改进我们的模式之改进单例模式的更多相关文章

  1. (原创)c++11改进我们的模式之改进访问者模式

    本次讲c++11改进我们的模式之改进访问者模式 访问者模式是GOF23个设计模式中比较复杂的模式之一,但是它的功能也很强大,非常适合稳定的继承层次中对象的访问,可以在不修改被访问对象的情况下,动态添加 ...

  2. (原创)c++11改进我们的模式之改进命令模式

    模式虽然精妙,却难完美,比如观察者模式中观察者生命周期的问题:比如访问者模式中循环依赖的问题等等:其它很多模式也存在这样那样的一些不足之处,如使用场景受限.实现复杂.不够简洁.不够通用等.但我觉得不足 ...

  3. (原创)c++11改进我们的模式之改进代理模式,实现通用的AOP框架

    c++11 boost技术交流群:296561497,欢迎大家来交流技术. 本次要讲的时候如何改进代理模式,具体来说是动态代理模式,动态代理模式一般实现AOP框架,不懂AOP的童鞋看这里.我前面的博文 ...

  4. (原创)c++11改进我们的模式之改进表驱动模式

    所谓表驱动法(Table-Driven Approach),简单讲是指用查表的方法获取值.表驱动是将一些通过较为复杂逻辑语句来得到数据信息的方式,通过查询表的方式来实现,将数据信息存放在表里.对于消除 ...

  5. (原创)c++11改进我们的模式之改进观察者模式

    和单例模式面临的是同样的问题,主题更新的接口难以统一,很难做出一个通用的观察者模式,还是用到可变模板参数解决这个问题,其次还用到了右值引用,避免多余的内存移动.c++11版本的观察者模式支持注册的观察 ...

  6. C++11在时空性能方面的改进

    C++11在时空性能方面的改进 这篇我们聊聊C++11在时间和空间上的改进点: 主要包括以下方面: 新增的高效容器:array.forward_list以及unordered containers: ...

  7. [原创].NET 分布式架构开发实战五 Framework改进篇

    原文:[原创].NET 分布式架构开发实战五 Framework改进篇 .NET 分布式架构开发实战五 Framework改进篇 前言:本来打算这篇文章来写DAL的重构的,现在计划有点改变.之前的文章 ...

  8. 第11章 享元模式(Flyweight Pattern)

    原文 第11章 享元模式(Flyweight Pattern) 概述:   面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是在某些情况下,对象的数量可能会太多,从而导致了运行时 ...

  9. [Java反射机制]用反射改进简单工厂模式设计

    如果做开发的工作,工厂设计模式大概都已经深入人心了,比较常见的例子就是在代码中实现数据库操作类,考虑到后期可能会有数据库类型变换或者迁移,一般都会对一个数据库的操作类抽象出来一个接口,然后用工厂去获取 ...

随机推荐

  1. ASP.NET MVC3-第02节-添加一个Controller (C#)

    前言 ---------------------------- 第01节[翻译]01-ASP.NET MVC 3介绍 ---------------------------- MVC是“model-v ...

  2. (原)tensorflow中finetune某些层

    转载请注明处处: http://www.cnblogs.com/darkknightzh/p/7608709.html 参考网址: https://kratzert.github.io/2017/02 ...

  3. CSS特效(弧光效果)

    代码很简单, 根据需要修改标签class和弧光效果的宽高位置就可以了. <!DOCTYPE html> <html lang="en"> <head& ...

  4. oracle安装后tnsnames.ora内容

    # tnsnames.ora Network Configuration File: D:\Develop\oracle11g\product\11.2.0\dbhome_1\network\admi ...

  5. Python装饰器几个有用又好玩的例子

    装饰器是一种巧妙简洁的魔术,类似于Java中的面向切面编程,我们可以再函数执行前.执行后.抛出异常时做一些工作.利用装饰器,我们可以抽象出一些共同的逻辑,简化代码.而简化代码的同时,就是在增加代码鲁棒 ...

  6. [Spring学习笔记 2 ]装配各种类型的属性 map,list,array,null,properties

    一.spring Ioc容器补充(1) Spring Ioc容器 DI(依赖注入): 注入的方式:设值方法注入setter(属性注入)/构造子注入(构造函数传入依赖的对象)/字段注入field(注解) ...

  7. >/dev/null 2>&1的含义

    转帖:http://www.cnblogs.com/dkblog/archive/2009/07/31/1980722.html os.system("/etc/init.d/winbind ...

  8. Nginx+FastCGI运行原理(一)

    1 实战Nginx与PHP(FastCGI)的安装.配置与优化 1.1 什么是 FastCGI FastCGI是一个可伸缩地.高速地在HTTP server和动态脚本语言间通信的接口.多数流行的HTT ...

  9. STAF进行分布式脚本分发----实践篇

    该博文理论支持文章:http://www.cnblogs.com/zhangfei/p/3169139.html 一.准备条件 1.安装STAF.由于其官网被墙了,所以大家可进入WAT群的网盘里去下载 ...

  10. ruby的json请求

    require 'net/http'require 'uri'require 'json' customers = [{    "id" => 1123,    " ...