设计模式之单例模式实现(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
原文地址:https://www.cnblogs.com/diysoul/p/8733914.html