1. 程式人生 > >設計模式之單例模式實現(C++)

設計模式之單例模式實現(C++)

pan sin ace pen bsp ati one delet friend

#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

設計模式之單例模式實現(C++)