三十九、定义宏,并添加注释

注意

  • 换行需添加换行符 “\”
  • 宏中不能使用 // 添加注释,注释必须写在续行符("")的前面,使用 /* — */进行注释
#ifndef SINGLETON_H
#define SINGLETON_H

#include <QMutex>
#include <QScopedPointer>

/**
 * 使用方法:
 * 1. 定义类为单例:
 *     class ConnectionPool {
 *         SINGLETON(ConnectionPool) // Here
 *     public:
 *
 * 2. 获取单例类的对象:
 *     Singleton<ConnectionPool>::getInstance();
 *     ConnectionPool &pool = Singleton<ConnectionPool>::getInstance();
 * 注意: 如果单例的类需要释放的资源和 Qt 底层的信号系统有关系,例如 QSettings,QSqlDatabase 等,
 *     需要在程序结束前手动释放(也就是在 main() 函数返回前调用释放资源的函数,参考 ConnectionPool 的调用),
 *     否则有可能在程序退出时报系统底层的信号错误,导致如 QSettings 的数据没有保存。
 */
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()) {
            //reset():delete目前指向的对象,调用其析构函数,将指针指向另一个对象other,所有权转移到other
            instance.reset(new T());
        }
        mutex.unlock();
    }
    /**
     * 获取智能指针动态创建的对象的指针有两种方法:QScopedPointer#data() 和 QScopedPointer#take()
     *     T *QScopedPointer::data() const返回指向对象的常量指针,QScopedPointer仍拥有对象所有权。
     * 所以通过data()返回过后就被自动删除了,从而导致mian函数中的p1变成了野指针,程序崩溃.
     *     使用T *QScopedPointer::take()也是返回对象指针,但QScopedPointer不再拥有对象所有权,而
     * 是转移到调用这个函数的caller,同时QScopePointer对象指针置为NULL
     */
    return *instance.data();
}

/*-----------------------------------------------------------------------------|
 |                               Singleton Macro                               |
 |----------------------------------------------------------------------------*/

/**
  * QScopedPointerDeleter 是 QScopedPointer 的默认实现,使用delete删除指针
  * 宏中不能使用 // 添加注释,换行续添加换行符 “\”
  */
#define SINGLETON(Class)                            \
private:                                            \
    Class();                                        \
    ~Class();                                       \
    Class(const Class &other);                      \
    Class& operator=(const Class &other);           \
    friend class Singleton<Class>; /* 注释必须写在续行符("\")的前面 */ \
    friend struct QScopedPointerDeleter<Class>;/* 末尾注释不需要加续行符 */
#endif // DBUTIL_H


发布了475 篇原创文章 · 获赞 120 · 访问量 42万+

猜你喜欢

转载自blog.csdn.net/panchang199266/article/details/104572502