模板类实现单例

要求编译器至少支持C++11

#include <utility>

template<typename T>
class Singleton
{
public:
    Singleton() = default;
    ~Singleton() = default;

    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    Singleton(Singleton&&) = delete;
    Singleton& operator=(Singleton&&) = delete;

    template<typename ...Args>
    static T& Instance(Args&&... args)
    {
        static T ins{ std::forward<Args>(args)... };
        return ins;
    }
};

以上代码创建单例时候可以根据T的构造函数传递参数来实例T,不传递参数就是使用默认构造函数构造单例类T。

使用示例

class A{
public:
    A(int a):m_a(a){};
    void add(){++m_a;}
    void sub(){--m_a;}
private:
    int m_a{0};
};

void testFunc()
{   
    Singleton<A>::Instance(100).add();
    Singleton<A>::Instance(100).sub();

    Singleton<A>::Instance().add();
    Singleton<A>::Instance().sub();

    // 这里的 Singleton<A>::Instance() 和Singleton<A>::Instance(100)是两个函数,返回的单例并不是同一个。
}

宏定义实现单例

要求编译器至少支持C++11

#define SINGLETON(Class)        \
public:                         \
	static Class &Instance()    \
	{                           \
		static Class ins;		\
		return ins;				\
	}                           \
private:                        \
    Class(Class&&) = delete; \
    Class& operator=(Class&&) = delete;\
    Class(const Class&) = delete; \
    Class& operator=(const Class&) = delete;\
    Class() = default;          \
    ~Class() = default;

以上代码定义了单例类的构造函数和析构函数均为编译器默认支持类型。创建单例类时候也不支持传递构造函数参数。
使用示例

class A{
SINGLETON(A)
public:
    A(int a):m_a(a){};
    void add(){++m_a;}
    void sub(){--m_a;}
private:
    int m_a{0};
};

void testFunc()
{   
    // 使用默认构造函数构造A()。并不会使用构造函数A(int a)来实例对象
    A::Instance().add();
    A::Instance().sub();
}