zoukankan      html  css  js  c++  java
  • (原创)c++11改进我们的模式之改进单例模式

    我会写关于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,欢迎大家来交流技术。

  • 相关阅读:
    如何高效处理bug?
    如何获取字符串函数的实现?
    数据处理-csv,pandas
    CentOS 下安装SAC(Seismic Analysis Code)
    CentOS安装使用ffmpeg
    Tensorflow问题记录 --pydot Failed to import pydot. You must install pydot and graphviz for pydotprint to work
    Tensorflow学习记录 --TensorFlow高效读取数据tfrecord
    Committee to boost development of Chinese language teachers
    Consensus-based decentralized auctions for robust task allocation
    Chinese market critical to US firms: US-China Business Council
  • 原文地址:https://www.cnblogs.com/qicosmos/p/3145019.html
Copyright © 2011-2022 走看看