设计模式-单例模式2(宏定义和模板实现)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010021282/article/details/54730204

上一篇讲了单例模式的基础使用,下面来看看单例模式更“高级”的使用方式。

宏定义实现:
如果使用之前的方式去实现单例类,就要为每一个类做相当繁琐的操作,而这些操作其实有很大一部分是高度类似的,我们没必要总是做这些无用功。
不妨,用两个宏来代替这些重复又高度类似的工作:

#include <mutex>
#include <memory>

#define  SINGLETON_IMPLEMENT(ClassName)                         \
public:                                                         \
    virtual ~ClassName(void) {};                               \
    static ClassName* GetInstance();                            \
private:                                                        \
        ClassName(void) {};                                     \
    ClassName(const ClassName&);                                \
    ClassName operator = (const ClassName&);                    \
    static std::shared_ptr<ClassName>    m_pInstance;           \
    static std::mutex                      m_mutex;             


#define SINGLETON_DECLARE(ClassName)                                        \
std::shared_ptr<ClassName> ClassName::m_pInstance;                          \
std::mutex  ClassName::m_mutex;                                             \
ClassName* ClassName::GetInstance()                                         \
{                                                                           \
    if (m_pInstance == NULL)                                                \
        {                                                                   \
        std::unique_lock<std::mutex>  lk(m_mutex);                          \
        if (m_pInstance == NULL)                                            \
            m_pInstance = std::shared_ptr<ClassName>(new ClassName());      \
        }                                                                   \
    return m_pInstance.get();                                               \
}               

上面的代码实现了两个宏:SINGLETON_IMPLEMENT和SINGLETON_DECLARE。

不妨将上面的代码放到一个头文件里面,需要的时候包含进来。

这样,实现的一个单例类,只有3个非常简单的操作:
1、包含上面的代码(头文件)
2、在类声明里面使用SINGLETON_IMPLEMENT,参数为自身类名
3、在类外调用SINGLETON_DECLARE,参数为自身类名

就像这样:

#include "Singleton.h" //里面包含上述代码
class MyClass
{
    SINGLETON_IMPLEMENT(MyClass)//类声明使用SINGLETON_IMPLEMENT
    public:
        void print() { cout << "I'm a singleton" << endl; }
};

SINGLETON_DECLARE(MyClass);//类外使用SINGLETON_DECLARE

int main()
{
    MyClass::GetInstance()->print();
    return 0;
}

只增加3行代码,就实现了一个单例类,是不是方便多了?

模板实现:

还有一种更灵活的方式,就是用模板实现单例:

#include <mutex>
#include <memory>

template <class T>
class Singleton
{
public:
    static T* GetInstance()
    {
        if (_instance == NULL)
        {
            std::unique_lock<std::mutex> lk(_mutex);
            if (_instance == NULL)
            {
                _instance = std::shared_ptr<T>(new T());
            }
        }
        return _instance.get();
    }

private:
    Singleton();
    ~Singleton();
    Singleton& operator=(const Singleton&);
    Singleton(const Singleton&);
    static std::mutex           _mutex;
    static std::shared_ptr<T>  _instance;
};

template<class T> 
std::mutex Singleton<T>::_mutex;
template<class T> 
std::shared_ptr<T>  Singleton<T>::_instance = NULL;

使用就更简单了,包含进来马上就可以用:

#include "Singleton.h"

class MyClass
{
public:
    MyClass() {};
    ~MyClass() {};
    void print() { cout << "I'm a singleton" << endl; }
};

int main()
{
    Singleton<MyClass>::GetInstance()->print();
    return 0;
}

模板方式虽然便捷,但是自定义的类本身却没有被限定不能被多次构造,这是一个弊端。

最后,附上完整代码:
http://pan.baidu.com/s/1bpKg50j

猜你喜欢

转载自blog.csdn.net/u010021282/article/details/54730204