• 设计模式之单例模式实现(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(3.);
            Singleton<SingleInstanceKlass>::getInstance(0);
            Singleton<SingleInstanceKlass>::getInstance("")->run();
        }
        print_position();
    
        return 0;
    }
    
    #endif
  • 相关阅读:
    [ lucene高级 ] lucene中的算法PriorityQueue
    [ lucene扩展 ] MoreLikeThis 相似检索
    排序08归并排序
    lucene中的数值型字段(NumericField)
    两三年前的搜索管理系统
    java中的集合包简要分析
    倒排索引基础
    散列02java中的hashMap
    Mysql数据库中InnoDB和MyISAM的差别
    ajax 乱码
  • 原文地址:https://www.cnblogs.com/diysoul/p/8733914.html
Copyright © 2020-2023  润新知