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();
}

 通過打印結果可以看到,無論是使用指針對象或者引用對象的方法,實際上操作的都是同一實例。

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