实现代码

Singleton 设计模式应用非常广泛,实现起来也很简单,无非是私有化若干个构造函数,“operator =” 操作符,以及提供一个静态的创建和销毁方法。但是对每个类都写这些雷同的代码是不能容忍的,使用宏把整个 Singleton 模式封装起来,无论是类的定义还是类的使用的极其简单。

我使用Singlton的方式一直是在应用程序启动时顺序创建,程序结束前反序销毁,并且都在同一个线程中进行,并且只调用一次,因此就没有加上 double check lock,而使用方式决定了不必这样做。

请看代码:

  • Singleton.hpp
#pragma once

#define SINGLETON_THIS(ClassName)        ClassName::GetThis()
#define SINGLETON_INSTANCE(ClassName)    ClassName::GetInstance()
#define SINGLETON_OBJECT(ObjName)        SINGLETON_INSTANCE(C##ObjName)

#define DEFINE_SINGLETON(ClassName)                                            \
    ClassName* ClassName::m_pThis = NULL;

#define DEFINE_P_THIS(ClassName)                                            \
        DEFINE_SINGLETON(ClassName)

#define DECLARE_SINGLETON_INTERFACE(ClassName)                                \
public:                                                                        \
    static ClassName* GetThis()        {return m_pThis;}                        \
    static ClassName& GetInstance() {return *m_pThis;}                        \
protected:                                                                    \
    static ClassName* m_pThis;

#define DECLARE_SINGLETON_CREATE_INSTANCE(ClassName)                        \
public:                                                                        \
    static BOOL CreateInstance()                                            \
    {                                                                        \
        if(!m_pThis)                                                        \
            m_pThis = new ClassName;                                        \
                                                                            \
        return m_pThis != NULL;                                                \
    }                                                                        \
                                                                            \
    static BOOL DeleteInstance()                                            \
    {                                                                        \
        if(m_pThis)                                                            \
        {                                                                    \
            delete m_pThis;                                                    \
            m_pThis = NULL;                                                    \
        }                                                                    \
                                                                            \
        return m_pThis == NULL;                                                \
    }

#define DECLARE_PRIVATE_DEFAULT_CONSTRUCTOR(ClassName)                        \
private:                                                                    \
    ClassName(){}

#define DECLARE_PRIVATE_COPY_CONSTRUCTOR(ClassName)                            \
private:                                                                    \
    ClassName(const ClassName&);                                            \
    ClassName& operator = (const ClassName&);

#define DECLARE_NO_COPY_CLASS(className)                                    \
        DECLARE_PRIVATE_COPY_CONSTRUCTOR(className)


#define DECLARE_SINGLETON_IMPLEMENT_NO_CREATE_INSTANCE(ClassName)            \
    DECLARE_SINGLETON_INTERFACE(ClassName)                                    \
    DECLARE_PRIVATE_DEFAULT_CONSTRUCTOR(ClassName)                            \
    DECLARE_PRIVATE_COPY_CONSTRUCTOR(ClassName)                                

#define DECLARE_SINGLETON_IMPLEMENT_NO_DEFAULT_CONSTRUCTOR(ClassName)        \
    DECLARE_SINGLETON_CREATE_INSTANCE(ClassName)                            \
    DECLARE_PRIVATE_COPY_CONSTRUCTOR(ClassName)

#define DECLARE_SINGLETON_IMPLEMENT(ClassName)                                \
    DECLARE_SINGLETON_IMPLEMENT_NO_DEFAULT_CONSTRUCTOR(ClassName)            \
    DECLARE_PRIVATE_DEFAULT_CONSTRUCTOR(ClassName)

#define DECLARE_SINGLETON_NO_DEFAULT_CONSTRUCTOR(ClassName)                    \
    DECLARE_SINGLETON_INTERFACE(ClassName)                                    \
    DECLARE_SINGLETON_IMPLEMENT_NO_DEFAULT_CONSTRUCTOR(ClassName)

#define DECLARE_SINGLETON(ClassName)                                        \
    DECLARE_SINGLETON_NO_DEFAULT_CONSTRUCTOR(ClassName)                        \
    DECLARE_PRIVATE_DEFAULT_CONSTRUCTOR(ClassName)


template<class T>
class CSingleObject
{
public:
    CSingleObject    ()    {T::CreateInstance();}
    ~CSingleObject    ()    {T::DeleteInstance();}
    T* GetPointer    ()    {return T::GetThis();}
    T& GetObject    ()    {return T::GetInstance();}
    BOOL IsValid    ()    {return GetPointer() != NULL;}
};
 #define DECLARE_SINGLE_OBJECT(ClassName) CSingleObject<ClassName> _##ClassName##_Single_Object_;

  • Singleton 类头文件(MyClass.h)
 #pragma once

#include "Singleton.hpp"

// 为使用方便,定义‘MyClass’代替‘CMyClass::GetInstance()’
#define MyClass    SINGLETON_INSTANCE(CMyClass)

class CMyClass
{
private:
    int x;
    int y;

public:
    int mix();

private:
    // 自定义构造函数(可选,一般情况下不需要自定义构造函数)
    CMyClass() : x(123), y(456) {}

    /***** 声明 Singleton *****/

    // 如果上面没有自定义构造函数,Singleton 声明为:
        // DECLARE_SINGLETON(CMyClass)
    // 否则声明为:
        DECLARE_SINGLETON_NO_DEFAULT_CONSTRUCTOR(CMyClass)
};
  • Singleton 类实现文件(MyClass.cpp)
#include "StdAfx.h"
#include "MyClass.h"

// 声明:CMyClass* CMyClass::m_pThis
DEFINE_SINGLETON(CMyClass)

int CMyClass::mix()
{
    return x * y;
}

使用方式

#include "stdafx.h"
#include "MyClass.h"

// 用 CMyClass::CreateInstance() 创建唯一实例
DECLARE_SINGLE_OBJECT(CMyClass)

int _tmain(int argc, _TCHAR* argv[])
{
    // 访问唯一实例
    int result = MyClass.mix();

    std::cout << result << endl;

    return 0;
}