linux开发

单例模式

单例模式的封面

用法:

1. 基础线程不安全版本 懒汉

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及以上) 懒汉

#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(推荐) 饿汉

class Singleton {
private:
    Singleton() {}  // 私有构造函数

public:
    static Singleton& getInstance() {
        static Singleton instance;  // C++11保证线程安全
        return instance;
    }
    
    // 禁止拷贝构造和赋值
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
};

4. 智能指针版本

#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. 模板通用版本

#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;

使用示例

#include <iostream>

class MyClass {
private:
    int value;
    MyClass() : value(0) {}  // 私有构造函数
    friend class Singleton<MyClass>;  // 允许Singleton访问私有构造函数

public:
    void setValue(int v) { value = v; }
    int getValue() const { return value; }
};

// 使用方式
int main() {
    // 使用Meyer's Singleton
    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)
  • 代码简洁
  • 性能较好(延迟初始化)

还有一种,采用双锁检查机制。

#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;