用法:
1. 基础线程不安全版本 懒汉
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Singleton { private: static Singleton* instance; Singleton() {}
public: static Singleton* getInstance() { if (instance == nullptr) { instance = new Singleton(); } return instance; } };
Singleton* Singleton::instance = nullptr;
|
2. 线程安全版本(C++11及以上) 懒汉
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include <mutex>
class Singleton { private: static Singleton* instance; static std::mutex mtx; Singleton() {}
public: static Singleton* getInstance() { std::lock_guard<std::mutex> lock(mtx); if (instance == nullptr) { instance = new Singleton(); } return instance; } };
Singleton* Singleton::instance = nullptr; std::mutex Singleton::mtx;
|
3. Meyer’s Singleton(推荐) 饿汉
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Singleton { private: Singleton() {}
public: static Singleton& getInstance() { static Singleton instance; return instance; } Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; };
|
4. 智能指针版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include <memory> #include <mutex>
class Singleton { private: static std::shared_ptr<Singleton> instance; static std::mutex mtx; Singleton() {}
public: static std::shared_ptr<Singleton> getInstance() { if (instance == nullptr) { std::lock_guard<std::mutex> lock(mtx); if (instance == nullptr) { instance = std::shared_ptr<Singleton>(new Singleton()); } } return instance; } Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; };
std::shared_ptr<Singleton> Singleton::instance = nullptr; std::mutex Singleton::mtx;
|
5. 模板通用版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include <mutex>
template<typename T> class Singleton { private: static T* instance; static std::mutex mtx;
public: static T* getInstance() { if (instance == nullptr) { std::lock_guard<std::mutex> lock(mtx); if (instance == nullptr) { instance = new T(); } } return instance; } Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; };
template<typename T> T* Singleton<T>::instance = nullptr;
template<typename T> std::mutex Singleton<T>::mtx;
|
使用示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <iostream>
class MyClass { private: int value; MyClass() : value(0) {} friend class Singleton<MyClass>;
public: void setValue(int v) { value = v; } int getValue() const { return value; } };
int main() { auto& singleton = Singleton::getInstance(); auto* myClass = Singleton<MyClass>::getInstance(); myClass->setValue(42); std::cout << "Value: " << myClass->getValue() << std::endl; return 0; }
|
推荐使用
对于大多数情况,推荐使用 Meyer’s Singleton 实现方式,因为它:
- 线程安全(C++11标准保证)
- 自动销毁(RAII)
- 代码简洁
- 性能较好(延迟初始化)
还有一种,采用双锁检查机制。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include <mutex> #include <atomic>
class Singleton { private: static std::atomic<Singleton*> instance; static std::mutex mtx; Singleton() {}
public: static Singleton* getInstance() { Singleton* tmp = instance.load(std::memory_order_relaxed); if (tmp == nullptr) { std::lock_guard<std::mutex> lock(mtx); tmp = instance.load(std::memory_order_relaxed); if (tmp == nullptr) { tmp = new Singleton(); instance.store(tmp, std::memory_order_relaxed); } } return tmp; } Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; };
std::atomic<Singleton*> Singleton::instance{nullptr}; std::mutex Singleton::mtx;
|