单例的模版+宏的实现

下面,对 单例的模版实现 使用宏进一步简化。

Singleton.h

在 Singleton.h 的最后面添加宏 SINGLETON

#ifndef SINGLETON_H
#define SINGLETON_H

#include <QMutex>
#include <QScopedPointer>

template <typename T>
class Singleton {
public:
    static T& getInstance();

    Singleton(const Singleton &other);
    Singleton<T>& operator=(const Singleton &other);

private:
    static QMutex mutex;
    static QScopedPointer<T> instance;
};


///                                                                          ///
///                            Singleton implementation                      ///
///                                                                          ///

template <typename T> QMutex Singleton<T>::mutex;
template <typename T> QScopedPointer<T> Singleton<T>::instance;

template <typename T>
T& Singleton<T>::getInstance() {
    if (instance.isNull()) {
        mutex.lock();
        if (instance.isNull()) {
            instance.reset(new T());
        }
        mutex.unlock();
    }

    return *instance.data();
}


///                                                                          ///
///                               Singleton Macro                            ///
///                                                                          ///

#define SINGLETON(Class)                        \
private:                                        \
    Class();                                    \
    ~Class();                                   \
    Class(const Class &other);                  \
    Class& operator=(const Class &other);       \
    friend class Singleton<Class>;              \
    friend struct QScopedPointerDeleter<Class>;

#endif // SINGLETON_H

ConfigUtil.h

#ifndef CONFIGUTIL_H
#define CONFIGUTIL_H

#include "Singleton.h" // [[1]]
#include <QString>

class ConfigUtil {
    SINGLETON(ConfigUtil) // [[2]]

public:
    QString getDatabaseName() const;
};

#endif // CONFIGUTIL_H

ConfigUtil.cpp

#include "ConfigUtil.h"
#include <QDebug>

ConfigUtil::ConfigUtil() {
    qDebug() << "ConfigUtil()";
}

ConfigUtil::~ConfigUtil() {
    qDebug() << "~ConfigUtil()";
}

QString ConfigUtil::getDatabaseName() const {
    return "Pirate";
}
现在实现单例的类,单例相关的代码,只需要:
  • 头文件 Singleton.h
  • 使用宏 SINGLETON

在 单例的智能指针+宏的实现 里用了两个宏,这里只用了一个,也算是个进步吧。

main.cpp

main.cpp 用于展示 ConfigUtil 的使用。

#include "ConfigUtil.h"
#include <QDebug>

int main(int argc, char *argv[]) {
    Q_UNUSED(argc)
    Q_UNUSED(argv)

    qDebug() << Singleton<ConfigUtil>::getInstance().getDatabaseName();
    qDebug() << Singleton<ConfigUtil>::getInstance().getDatabaseName();

    return 0;
}

输出:

ConfigUtil()
"Pirate"
"Pirate"
~ConfigUtil()

通过上面对代码的优化,使用模版和宏,实现了大量代码的复用,只需要简单的几条语句,就能实现一个单例的类,让我们把更多的精力放在类的业务逻辑上,而不是浪费在单例实现的那些模版代码上。

资源下载

Singleton 相关的代码和文件可以在这里下载:http://qtdebug.com/download/Singleton.7z


转载:http://qtdebug.com/Singleton-5-TemplateMacro.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值