文章目錄
- 看兩個栗子
- 傳統指針版單例模式
- 現代靜態變量版單例模式
- 分析
- 結論
看兩個栗子
傳統指針版單例模式
class Singleton {
private:// 私有化構造函數Singleton() {}// 禁止拷貝構造函數Singleton(const Singleton&) = delete;// 禁止拷貝賦值操作Singleton& operator=(const Singleton&) = delete;// 靜態變量,存儲唯一實例static Singleton* instance;public:// 靜態方法,用于獲取實例static Singleton* getInstance() {if (instance == nullptr) {instance = new Singleton();}return instance;}// 其他成員函數void Display() {//...}
};// 在類外初始化靜態成員變量
Singleton* Singleton::instance = nullptr;int main() {// 獲取單例類的實例Singleton* mySingleton = Singleton::getInstance();mySingleton->Display();
}
現代靜態變量版單例模式
class Singleton {
private:// 私有化構造函數Singleton() {}// 禁止拷貝構造函數Singleton(const Singleton&) = delete;// 禁止拷貝賦值操作Singleton& operator=(const Singleton&) = delete;public:// 靜態方法,用于獲取實例static Singleton& getInstance() {static Singleton instance;return instance;}// 其他成員函數void Display() {//...}
};int main() {// 獲取單例類的實例Singleton& mySingleton = Singleton::getInstance();mySingleton.Display();
}
分析
💥兩種單例模式的優劣和區別:
- 簡潔性
- 傳統指針版:需要手動管理指針(如初始化和銷毀),代碼稍復雜。
- 現代靜態變量版:代碼簡潔,避免了指針管理。
- 線程安全
- 傳統指針版:在多線程環境下,手動管理靜態實例的創建需要考慮線程安全問題,通常需要加入互斥鎖。
- 現代靜態變量版:C++11 以后,局部靜態變量的初始化是線程安全的,天然支持多線程環境。
- 內存管理
- 傳統指針版:需要顯式刪除靜態實例對象,避免內存泄漏。
- 現代靜態變量版:局部靜態變量由編譯器自動管理其生命周期,不需要手動刪除。
🎉推薦:
在大多數情況下,我更推薦使用現代靜態變量版的單例模式,原因如下:
- 簡潔明了:代碼更簡潔,更容易理解和維護。
- 線程安全:C++11 及其之后版本保證了線程安全的初始化。
- 自動內存管理:不需要手動管理內存,減少了內存泄漏的風險。
然而,在某些特定場景下,可能會有不同的考慮。例如,如果你需要在單例銷毀時執行特殊的清理操作或需要在不支持 C++11 的編譯器上編譯代碼,那么傳統的單例模式可能會更適合。
結論
現代靜態變量版的單例模式在大多數情境下都更符合當前的開發需求和標準,推薦優先采用。但在設計模式的選擇上仍需根據具體需求和環境進行適當的調整。