C++设计模式——单例模式 (一)

      单例模式:一个类只能创建一个对象。单例模式是C++中常用的一种设计模式,熟悉Qt的朋友肯定清楚QApplication实际也是采用的单例模式,并且为用户提供了一个全局的指针对象 qApp。我们先看看Qt中对於单例的实现:


#define qApp QCoreApplication::instance()

class Q_CORE_EXPORT QCoreApplication : public QObject
{
    Q_OBJECT
public:
    QCoreApplication(int &argc, char **argv, int _internal = ApplicationFlags);
    ~QCoreApplication();
    static QCoreApplication *instance() { return self; } // 返回对象本身
private:
	 static QCoreApplication *self;
};


QCoreApplication::QCoreApplication(int &argc, char **argv, int _internal)
: QObject(*new QCoreApplicationPrivate(argc, argv, _internal))
{
    Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");
    QCoreApplication::self = this; 
}

QCoreApplication::~QCoreApplication()
{
    self = 0;
    // ...
}

看完上面的代码,有点启发。现在回到我们的主题,我们如何自己实现单例模式呢。

单例模式分为饿汉式懒汉式两种,

懒汉式与饿汉式区别
单例模式 优点 缺点
懒汉式 只有在调用相应的方法时,才会构造对象 每次都要进行判断,程序进行慢
饿汉式 不管需不需要对象空间,都先提前布局好对象空间; 存在内存空间的浪费

 

 

 

 

 

#include <QCoreApplication>
#include <iostream>
#include <QDebug>
using namespace  std;

/**
 * @brief The mySingleton class 指针对象模式
 * 维护一个唯一的全局指针对象
 */

class mySingleton{
private:
    mySingleton(){}
public:
    static mySingleton* getInstance(){
#ifndef Hungary_Model // 饿汉模式
#else // 懒汉模式
        if(m_ps1 == NULL) m_ps1 = new mySingleton;
#endif
        return m_ps1;
    }
    static void freeInstance(){
        if(m_ps1){
            delete m_ps1;
            m_ps1 = NULL;
        }
    }
private:
    static mySingleton* m_ps1;
};

#ifndef Hungery_Model // 饿汉模式
mySingleton *mySingleton::m_ps1 = new mySingleton;
#else  // 懒汉模式
mySingleton *mySingleton::m_ps1 = NULL;
#endif


/**
 * @brief The RenfrenceSingleton class 引用模式
 * 维护一个全局的单例对象
 */
class RenfrenceSingleton
{
public:
    static RenfrenceSingleton rSingleton;
private:
    RenfrenceSingleton() {
        cout << "RenfrenceSingleton constructor" << endl;
    }
public:
    static RenfrenceSingleton& getInstance(){
        return rSingleton;
    }
};
RenfrenceSingleton RenfrenceSingleton::rSingleton;



int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    mySingleton* mp1 = mySingleton::getInstance();
    mySingleton* mp2 = mySingleton::getInstance();
    cout << "[ptr singleton] " << mp1 << "   "<< mp2 << endl;
    mySingleton::freeInstance();

    RenfrenceSingleton& r1 = RenfrenceSingleton::getInstance();
    RenfrenceSingleton& r2 = RenfrenceSingleton::getInstance();
    cout << "[reference singleton] " << &r1 <<"  " <<  &r2 << endl;

    return a.exec();
}

 通过打印结果可以看到,无论是使用指针对象或者引用对象的方法,实际上操作的都是同一实例。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章