设计模式——单例模式(singleton)

文章目录

引言

相信大家对单例模式都不陌生,本博客主要结合C++17写一个相对标准的单例模式框架,并进行讲解。

这也是创建型模式的最后一篇,大家感兴趣的可以看看其余4个创建型模式:

  1. 抽象工厂
  2. 生成器模式
  3. 工厂方法
  4. 原型模式

单例代码实现

单类简易版

cpp 复制代码
class Singleton {
public:
    // 获取唯一实例的全局访问点(懒加载 + 线程安全)
    static Singleton& instance() noexcept {
        static Singleton instance; // C++11 起保证线程安全
        return instance;
    }

    // 禁止拷贝和移动
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    Singleton(Singleton&&) = delete;
    Singleton& operator=(Singleton&&) = delete;

    // 提供示例方法
    void doSomething() {
        std::cout << "Singleton working at " << this << std::endl;
    }

private:
    // 构造函数设为私有,防止外部创建
    Singleton() {
        std::cout << "Singleton constructed.\n";
    }

    ~Singleton() {
        std::cout << "Singleton destroyed.\n";
    }
};

// 测试
int main() {
    Singleton::instance().doSomething();
    Singleton::instance().doSomething();
}

模板通用版

cpp 复制代码
// === 通用单例模板 ===
template <typename T>
class Singleton {
public:
    static T& instance() {
        static T instance; // C++11+ 确保线程安全
        return instance;
    }

protected:
    Singleton() = default;
    ~Singleton() = default;

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

// === 具体的单例类 ===
class Logger : public Singleton<Logger> {
    friend class Singleton<Logger>;  // 允许 Singleton 访问私有构造

private:
    Logger() = default;              // 外部无法 new Logger()
    ~Logger() = default;

public:
    void log(const std::string& message) {
        std::cout << "[LOG] " << message << std::endl;
    }
};

// === 使用示例 ===
int main() {
    // 获取 Logger 的唯一实例
    auto& logger = Logger::instance();

    // 使用单例对象
    logger.log("System initialized.");
    logger.log("User logged in.");

    // 再次获取 instance,返回同一个对象
    auto& logger2 = Logger::instance();
    logger2.log("Still the same instance!");

    // 验证地址一致
    std::cout << "logger addr: " << &logger << std::endl;
    std::cout << "logger2 addr: " << &logger2 << std::endl;

    return 0;
}
相关推荐
极客智造2 小时前
C++ 标准 IO 流全详解:cin /cout/get /getline 原理、用法、区别与避坑
c++·io
charlie1145141912 小时前
嵌入式C++工程实践第20篇:GPIO 输入模式内部电路 —— 芯片是如何“听“到外部信号的
开发语言·c++·stm32·单片机
消失的旧时光-19432 小时前
Spring Boot 工程化进阶:统一返回 + 全局异常 + AOP 通用工具包
java·spring boot·后端·aop·自定义注解
Cosolar2 小时前
提示词工程面试题系列 - Zero-Shot Prompting 和 Few-Shot Prompting 的核心区别是什么?
人工智能·设计模式·架构
NE_STOP2 小时前
Redis--发布订阅命令和Redis事务
java
PAC_3Dame3 小时前
记一次真实的线上OOM
java
SunnyDays10113 小时前
如何在Java中将Word文档转换为图像(JPEG、PNG或SVG)
java
Lumos_7773 小时前
Linux -- 线程
java·jvm·算法
知兀3 小时前
【MybatisPlus】后端用枚举类,数据库用tinyint,存在枚举类型转换
java
StockTV3 小时前
印度股票实时数据 NSE和BSE的实时行情、K 线及指数数据
java·开发语言·spring boot·python