一、核心思想

保障一个类在系统中只有一个实例,并提供一个全局访问点

二、适用场景

场景

说明

配置管理器(ConfigManager)

程序中所有模块共享同一份配置

日志系统(Logger)

保证日志输出统一、线程安全

线程池 / 数据库连接池

管理有限资源

全局状态管理器

保存全局状态(如 UI 主题、系统参数等)

三、实现方式

1、懒汉式

需要时才创建

优点:延迟加载

缺点:手动管理内存/多线程竞争下可能出错(所以需要进行加锁)

#include <iostream>
#include <mutex>

class Logger {
public:
static Logger* getInstance() {
    std::lock_guard<std::mutex> lock(mtx);
    if (!instance) {
        instance = new Logger();
    }
    return instance;
}

    void log(const std::string& msg) {
    std::cout<<"[LOG]:"<<msg<<std::endl;
}
private:
    static Logger* instance; //唯一指针
    static std::mutex mtx; //线程安全
    Logger(){std::cout<<"Logger constructed\n";}; //私有构造
    Logger(const Logger&) = delete;
    Logger& operator=(const Logger&) = delete;
};

Logger* Logger::instance = nullptr;
std::mutex Logger::mtx;

int main() {
    Logger::getInstance()->log("System started");
    Logger::getInstance()->log("Running...");
    return 0;
}


//运行结果
Logger constructed
[LOG]:System started
[LOG]:Running...

2、懒汉式升级版

优点:线程安全,初始化只执行一次

缺点:依旧是指针管理(可能内存泄漏)

#include <iostream>
#include <mutex>

class Logger {
public:
static Logger* getInstance() {
    std::call_once(flag,[](){instance=new Logger();});
    return instance;
}

    void log(const std::string& msg) {
    std::cout<<"[LOG]:"<<msg<<std::endl;
}
private:
    static Logger* instance; //唯一指针
    static std::once_flag flag;
    Logger(){std::cout<<"Logger constructed\n";}; //私有构造
};

Logger* Logger::instance = nullptr;
std::once_flag Logger::flag;

int main() {
    auto* logger = Logger::getInstance();
    logger->log("Thread-safe singleton with call_once!");
    return 0;
}

//执行结果
Logger constructed
[LOG]:Thread-safe singleton with call_once!

3、饿汉式

程序启动时立即创建实例,线程安全(因为静态对象在初始化时保证原子性)

优点:实现最简单/完全线程安全/无需手动释放

#include <iostream>

class Logger {
private:
    Logger() {std::cout<<"Logger constructed"<<std::endl;}
public:
    static Logger& getInstance() {
        static Logger instance;
        return instance;
    }
    void log(std::string msg) {
        std::cout<<"[LOG]:"<<msg<<std::endl;
    }

    Logger(const Logger&) = delete;
    Logger& operator=(const Logger&) = delete;
};

int main() {
    auto& logger = Logger::getInstance();
    logger.log("Eager singleton initialized at startup!");
}

四、典型应用:日志安全

单例+线程安全+文件输出

#include <iostream>
#include <fstream>
#include <mutex>

class FileLogger {
public:
//通过instance来获取实例,所以避免了创建多个实例
    static FileLogger& instance() {
        static FileLogger logger;
        return logger;
    }
    void log(const std::string& message) {
        std::lock_guard<std::mutex> lock(mtx);
        ofs<<"[LOG]:"<<message<<"\n";
    }
private:
    std::ofstream ofs;
    std::mutex mtx;
    FileLogger() {
        ofs.open("app.log",std::ios::app);
    }
};

int main() {
    auto& logger=FileLogger::instance();
    logger.log("my logger system");
}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐