c++11 singleton 类模板实现

原创 2014年11月29日 18:38:50

使用单例从来没有如此容易和省心过, 传统单实例类模板singleton, 二段式构造单实例模板delayed

singleton.h:

#ifndef _SINGLETON_H_
#define _SINGLETON_H_
#include <new>
#include <memory>
#include <functional>

#if defined(_ENABLE_MULTITHREAD)
#include <mutex>
#endif

namespace purelib {
    namespace gc {

        // CLASS TEMPLATE singleton forward decl
        template<typename _Ty, bool delayed = false>
        class singleton;

        /// CLASS TEMPLATE singleton
        /// the managed singleton object will be destructed after main function.
        template<typename _Ty>
        class singleton<_Ty, false>
        {
            typedef singleton<_Ty, false> _Myt;
            typedef _Ty* pointer;
        public:
            template<typename ..._Args>
            static pointer instance(_Args...args)
            {
                if (nullptr == _Myt::__single__.get())
                {
#if defined(_ENABLE_MULTITHREAD)
                    _Myt::__mutex__.lock();
#endif
                    if (nullptr == _Myt::__single__.get())
                    {
                        _Myt::__single__.reset(new(std::nothrow) _Ty(args...));
                    }
#if defined(_ENABLE_MULTITHREAD)
                    _Myt::__mutex__.unlock();
#endif
                }
                return _Myt::__single__.get();
            }

            static void destroy(void)
            {
                if (_Myt::__single__.get() != nullptr)
                {
                    _Myt::__single__.reset();
                }
            }

        private:
            static std::unique_ptr<_Ty> __single__;
#if defined(_ENABLE_MULTITHREAD)
            static std::mutex    __mutex__;
#endif
        private:
            singleton(void) = delete; // just disable construct, assign operation, copy construct also not allowed.
        };

        /// CLASS TEMPLATE singleton, support delay init with variadic args
        /// the managed singleton object will be destructed after main function.
        template<typename _Ty>
        class singleton<_Ty, true>
        {
            typedef singleton<_Ty, true> _Myt;
            typedef _Ty* pointer;
        public:
            template<typename ..._Args>
            static pointer instance(_Args...args)
            {
                if (nullptr == _Myt::__single__.get())
                {
#if defined(_ENABLE_MULTITHREAD)
                    _Myt::__mutex__.lock();
#endif
                    if (nullptr == _Myt::__single__.get())
                    {
                        _Myt::__single__.reset(new(std::nothrow) _Ty());
                        if (_Myt::__single__ != nullptr)
                            _Myt::delay_init(args...);
                    }
#if defined(_ENABLE_MULTITHREAD)
                    _Myt::__mutex__.unlock();
#endif
                }
                return _Myt::__single__.get();
            }

            static void destroy(void)
            {
                if (_Myt::__single__.get() != nullptr)
                {
                    _Myt::__single__.reset();
                }
            }

        private:

            template<typename _Fty, typename..._Args>
            static void delay_init(const _Fty& memf, _Args...args)
            { // init use specific member func with more than 1 args
                std::mem_fn(memf)(_Myt::__single__.get(), args...);
            }

            template<typename _Fty, typename _Arg>
            static void delay_init(const _Fty& memf, const _Arg& arg)
            { // init use specific member func with 1 arg
                std::mem_fun(memf)(_Myt::__single__.get(), arg);
            }

            template<typename _Fty>
            static void delay_init(const _Fty& memf)
            { // init use specific member func without arg
                std::mem_fun(memf)(_Myt::__single__.get());
            }

            static void delay_init(void)
            { // if no member func specificed, use preferred func 'init'
                _Myt::__single__->init();
            }

        private:
            static std::unique_ptr<_Ty> __single__;
#if defined(_ENABLE_MULTITHREAD)
            static std::mutex    __mutex__;
#endif
        private:
            singleton(void) = delete; // just disable construct, assign operation, copy construct also not allowed.
        };

        template<typename _Ty>
        std::unique_ptr<_Ty> singleton<_Ty, false>::__single__;
#if defined(_ENABLE_MULTITHREAD)
        template<typename _Ty>
        std::mutex    singleton<_Ty, false>::__mutex__;
#endif

        template<typename _Ty>
        std::unique_ptr<_Ty> singleton<_Ty, true>::__single__;
#if defined(_ENABLE_MULTITHREAD)
        template<typename _Ty>
        std::mutex    singleton<_Ty, true>::__mutex__;
#endif

        // TEMPLATE alias
        template<typename _Ty>
        using delayed = singleton < _Ty, true > ;
    };
};

#endif

/*
* Copyright (c) 2012-2014 by X.D. Guo  ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
V3.0:2011 */




测试代码:

#include <functional>
#include "singleton.h"

class SoftwareManager
{
public:
    SoftwareManager()
    {

    }
    SoftwareManager(const char* name, int age, bool developer)
    {
        this->name = name;
        this->age = age;
        this->developer = developer;
    }
    ~SoftwareManager()
    {

    }

    void init(){}

    void doInit(const char* name, int age, bool developer)
    {
        this->name = name;
        this->age = age;
        this->developer = developer;
    }

private:
    std::string name;
    int age = 1;
    bool developer = false;
};

int main(int argc, char** argv)
{   
    purelib::gc::delayed<SoftwareManager>::instance(&SoftwareManager::doInit, "hello", 19, true);
    
    auto check = purelib::gc::delayed<SoftwareManager>::instance();

    purelib::gc::delayed<SoftwareManager>::destroy();

    check = purelib::gc::delayed<SoftwareManager>::instance();
    
    purelib::gc::singleton<SoftwareManager>::instance("hello", 19, true);

    check = purelib::gc::singleton<SoftwareManager>::instance();
    return 0;
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

c++11单实例(singleton)初始化的几种方法(memory fence,atomic,call_once)

单实例模式(singleton)下要求一个类只能有一个实例,如何保证只创建一个实例?类的静态成员延迟初始化要求静态成员只能被初始化一次,也有类似的问题。 在单线程环境下,这事儿很好办。Singlet...
  • 10km
  • 10km
  • 2015年11月11日 09:26
  • 5214

C++ 线程安全的singleton如何实现

线程安全的C++ 单例饿汉模式template class Singleton { private: Singleton() {} Singleton (co...
  • fall221
  • fall221
  • 2016年02月27日 14:07
  • 1424

C++11单例模式,另附C++11令CPU占用率为sin曲线

C++11单例模式,另附C++11令CPU占用率为sin曲线

C++完美实现Singleton模式

Singleton模式是常用的设计模式之一,但是要实现一个真正实用的设计模式却也不是件容易的事情。 1.         标准的实现 class Singleton { public:        ...

C++ Singleton模式

Singleton模式是常用的设计模式之一,但是要实现一个真正实用的设计模式却也不是件容易的事情。 1.标准的实现 class Singleton { public:        static Si...

C++中实现Singleton的正确方法

原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和本声明,否则将追究法律责任。http://blog.csdn.net/hzliyun/article/details/7178...
  • hzliyun
  • hzliyun
  • 2012年01月05日 17:14
  • 3188

探究 C++ Singleton(单例模式)

一、静态化并不是单例模式   初学者可能会犯的错误, 误以为把所有的成员变量和成员方法都用 static 修饰后, 就是单例模式了: class Singleton { public:...

C++(Singleton)更高效单例模式实现

单例模式(来自google,了解可以跳过下面文字叙述) 单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全...

每天一题(48) - C++实现Singleton模式

饿汉模式 代码(1) //.h文件 class Singleton { public: static Singleton& GetInstance(); private: Singleton(){...

C++ 中的 Singleton 实现

C++ 中的 Singleton 实现 关键字:ANSI C++, Singleton, static member, initialize, auto_ptr, std, STL , implem...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c++11 singleton 类模板实现
举报原因:
原因补充:

(最多只允许输入30个字)