1. 程式人生 > 其它 >Qt 單例模式的實現 ,自定義巨集實現方法

Qt 單例模式的實現 ,自定義巨集實現方法

最簡單的寫法:

static MyClass* MyClass::Instance()
{
    static MyClass inst;
    return &inst;
}

進階寫法:

static MyClass* MyClass::Instance()
{
    static QMutex mutex;
    static QScopedPointer<MyClass> inst;
    if (Q_UNLIKELY(!inst)) {
        mutex.lock();
        if (!inst) {
            inst.reset(
new MyClass); } mutex.unlock(); } return inst.data(); }

既保證了執行緒安全又防止了記憶體洩漏,效率也沒降低太多,簡直完美。

可惜每次都要重複這麼幾行實在麻煩,於是寫了一個

範型模板類:

template <class T>
class Singleton
{
public:
    static T* Instance()
    {
        static QMutex mutex;
        static QScopedPointer<T> inst;
        
if (Q_UNLIKELY(!inst)) { mutex.lock(); if (!inst) { inst.reset(new T); } mutex.unlock(); } return inst.data(); } };

使用的時候直接這樣:

MyClass* inst = Singleton<MyClass>::Instance();

除了用模板類,還可以利用c++中強大的巨集:

#define DECLARE_SINGLETON(Class) \
Q_DISABLE_COPY(Class) \
public: \ static Class* Instance() \ { \ static QMutex mutex; \ static QScopedPointer<Class> inst; \ if (Q_UNLIKELY(!inst)) { \ mutex.lock(); \ if (!inst) inst.reset(new Class); \ mutex.unlock(); \ } \ return inst.data(); \ }

然後宣告的時候,填加一行這個巨集:

class MyClass
{
    DECLARE_SINGLETON(MyClass);    // 宣告單例模式
    //...
}

當然,為了要保證真的是單例模式,還要把建構函式限制為private,不然以後什麼時候忘記了這碼事,在外面又new了一下就不好了。

另外Qt本身自帶了一個巨集Q_GLOBAL_STATIC,也有類似單例模式的效果,QThreadPool::globalInstance()函式的實現就是利用了這個巨集。不過它的主要用處是宣告全域性變數,和Singleton還是有差別的。