設計模式——單例模式(C++)

這個模式應該是設計模式中最簡單的一個了,可分爲懶漢式餓漢式

下面就分別貼上代碼:

/*****************************************
Copyright (c) 2016 Jingshuang Hu

@filename:main.cpp
@datetime:2016.09.13
@author:HJS
@e-mail:[email protected]
@blog:http://blog.csdn.net/hujingshuang
*****************************************/
#include <iostream>

using namespace std;

// 懶漢式:也就是說在需要創建實例的時候,才調用該函數來創建,不需要的時候就不創建,起到lazy loading的作用。
// 這種最基本的寫法線程不安全。如果加同步鎖,可以解決線程安全問題,但同時會導致效率低下。
class Singleton {
private:
    static Singleton* singleton;
    Singleton() {}                              // 私有
    ~Singleton() {}
    Singleton(const Singleton&);                // 聲明爲私有,只聲明不實現,明確拒絕編譯器默認的拷貝構造函數
    Singleton& operator=(const Singleton);      // 聲明爲私有,只聲明不實現,明確拒絕編譯器默認的賦值操作函數
public:
    static Singleton* getInstance() {
        if (singleton == NULL) {
            singleton = new Singleton();        // 調用的時候才創建實例
        }
        return singleton;
    }
};
Singleton* Singleton::singleton = NULL;         // 類外初始化

int main() {
    Singleton* singleton1 = Singleton::getInstance();
    Singleton* singleton2 = Singleton::getInstance();

    if (singleton1 == singleton2) {             // 創建的是同一個實例
        cout << "equal" << endl;
    }
    system("pause");
    return 0;
}
// 這是一種餓漢式方法,程序一開始就初始化靜態變量(即:創建了Singleton對象)
class Singleton {
private:
    static Singleton singleton;
    Singleton() {
        cout << "ctor" << endl;
    }
    ~Singleton() {
        cout << "dctor" << endl;
    }
    Singleton(const Singleton&);
    Singleton& operator=(const Singleton&);
public:
    static Singleton* getInstance() {       // 返回指針
        cout << "instance" << endl;
        return &singleton;
    }
    void fun() {
        cout << "fun" << endl;
    }
};
Singleton Singleton::singleton;

// 這是一種不好的做法,因爲這裏的singleton被動態的初始化,無法保證編譯器一定先將singleton初始化
// 因此Singleton::singleton的調用,可能傳回一個尚未構造的函數,因此導致使用該類成員函數出錯!(書《Modern C++ Design》)
int main() {
    Singleton::getInstance()->fun();
    Singleton* singleton1 = Singleton::getInstance();
    Singleton* singleton2 = Singleton::getInstance();

    if (singleton1 == singleton2) {         // 創建的是同一個實例
        cout << "equal" << endl;
    }
    system("pause");
    return 0;
}
// 引用版
class Singleton {
private:
    static Singleton* singleton;
    Singleton() {
        cout << "ctor" << endl;
    }
    ~Singleton() {
        cout << "dctor" << endl;
    }
    Singleton(const Singleton&);
    Singleton& operator=(const Singleton&);
public:
    static Singleton& getInstance() {       // 返回引用,相對指針要安全
        cout << "instance" << endl;
        return *singleton;
    }
    void fun() {
        cout << "fun" << endl;
    }
};
Singleton* Singleton::singleton;

// 這是一種不好得做法,因爲這裏的singleton被動態的初始化,無法保證編譯器一定先將singleton初始化
// 因此Singleton::singleton的調用,可能傳回一個尚未構造的函數,因此導致使用該類成員函數出錯!
int main() {
    Singleton::getInstance().fun();         // 在不同的編譯器上可能會出錯
    Singleton& singleton1 = Singleton::getInstance();
    Singleton& singleton2 = Singleton::getInstance();

    if (&singleton1 == &singleton2) {
        cout << "equal" << endl;
    }
    system("pause");
    return 0;
}
// 這是一種懶漢式做法,而且是線程安全的
class Singleton {
private:
    Singleton() {}
    ~Singleton(){};
    Singleton(const Singleton&);
    Singleton& operator=(const Singleton);
public:
    static Singleton& getIntance() {
        static Singleton singleton;         // 局部靜態類變量,其初始化發生在第一次定義時(也就是第一次調用此函數時)
        return singleton;
    }
    void fun() {
        cout << "fun" << endl;
    }
};

int main() {
    Singleton& singleton1 = Singleton::getIntance();
    Singleton& singleton2 = Singleton::getIntance();
    
    if (&singleton1 == &singleton2) {
        cout << "equal" << endl;
    }

    system("pause");
    return 0;
}
// 餓漢式:也就是說程序一開始就創建實例,不管用沒用到,保證了線程安全,但未起到lazy loading的效果。
class Singleton {
private:
    static Singleton* singleton;
    Singleton() {}
    ~Singleton() {}
    Singleton(const Singleton&);
    Singleton& operator=(const Singleton);
public:
    static Singleton* getInstance() {
        return singleton;
    }
    void fun() {
        cout << "fun" << endl;
    }
};
Singleton* Singleton::singleton = new Singleton();          // 不管需不需要,程序一上來就給創建實例

int main() {
    Singleton* singleton1 = Singleton::getInstance();
    Singleton* singleton2 = Singleton::getInstance();

    if (singleton1 == singleton1) {
        cout << "equal" << endl;
    }

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