卡码笔记
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
  • 基础与语法

  • 面向对象

    • C++构造函数有几种,分别什么作用?
    • 什么是构造函数和析构函数?构造函数和析构函数可以是虚函数吗?为什么?
    • C++的重载和重写,以及它们的区别和实现方式
    • C++怎么实现多态
    • C++中的虚函数和纯虚函数有什么区别?
    • 虚函数怎么实现的?
    • 虚函数表是什么
    • 多重继承的优缺点及菱形继承问题
    • 如何禁止一个类被继承
    • 深拷贝和浅拷贝的区别?
    • this指针的原理
    • C++如何实现一个单例模式?
      • 简要回答
      • 详细回答
      • 代码示例
      • 知识拓展
  • STL 与容器

  • 内存管理

  • C++11 与现代 C++

  • 智能指针

  • 并发与 I/O

# C++如何实现一个单例模式?

# 简要回答

单例模式(Singleton Pattern)确保某个类在程序运行期间只能有一个实例,并提供一个全局访问点。

常见的 C++ 实现方式:

饿汉式:程序启动时立即创建

懒汉式:第一次使用时才创建,线程不安全

双检锁(懒汉式 + 线程安全):加锁或使用 std::call_once

C++11 局部静态变量(Magic Static):推荐使用这样,因为这种情景下线程是安全的

# 详细回答

单例模式通过以下机制确保类的唯一性:

权限控制:将构造函数、拷贝构造函数和赋值运算符设为私有或删除,防止外部实例化和拷贝

静态管家:类内部维护一个静态成员变量来保存唯一实例

全局访问点:提供公共静态方法(通常命名为getInstance)作为获取实例的唯一入口

  • 每种单例模式的特点

饿汉式(Eager Initialization)

特点:程序启动时就创建实例

优点:实现简单,线程安全

缺点:可能造成资源浪费(实例未被使用时也占用内存)

class Singleton {
private:
    static Singleton* instance;
    Singleton() {}
public:
    static Singleton* getInstance() {
        return instance;
    }
};
// 程序启动时初始化
Singleton* Singleton::instance = new Singleton();
1
2
3
4
5
6
7
8
9
10
11

懒汉式(Lazy Initialization)

特点:首次请求时才创建实例

优点:资源利用率高

缺点:基础实现非线程安全

class Singleton {
private:
    static Singleton* instance;
    Singleton() {}

public:
    static Singleton* getInstance() {
        if (!instance)
            instance = new Singleton();
        return instance;
    }
};
// 初始化静态成员
Singleton* Singleton::instance = nullptr;
1
2
3
4
5
6
7
8
9
10
11
12
13
14

双检锁(Double-Checked Locking)

特点:懒加载+线程安全

原理:两次检查实例是否存在,中间加锁

class Singleton {
private:
    static Singleton* instance;
    static std::mutex mtx;
    Singleton() {}
public:
    static Singleton* getInstance() {
        if(instance == nullptr) {
            std::lock_guard<std::mutex> lock(mtx);
            if(instance == nullptr) {
                instance = new Singleton();
            }
        }
        return instance;
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

局部静态变量(Magic Static, C++11推荐)

特点:利用C++11的静态局部变量线程安全特性

优点:代码简洁,自动线程安全,自动销毁

class Singleton {
private:
    Singleton() {}
public:
    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }
};
1
2
3
4
5
6
7
8
9

# 代码示例

现代C++推荐实现:局部静态变量,这是用的最多的,下面给出一个这种情况下的例子

#include <iostream>

class Singleton {
public:
    // 删除拷贝构造和赋值操作
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    // 全局访问点
    static Singleton& getInstance() {
        static Singleton instance; // 线程安全初始化(C++11)
        return instance;
    }

    // 示例方法
    void log(const std::string& message) {
        std::cout << "[LOG] " << message << std::endl;
    }

private:
    // 私有构造函数
    Singleton() { std::cout << "Singleton created\n"; }
    ~Singleton() { std::cout << "Singleton destroyed\n"; }
};

int main() {
    Singleton::getInstance().log("Hello World");
    Singleton::getInstance().log("Another message");
    return 0;
}
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

# 知识拓展

  • 单例模式的优缺点

优点:

严格控制实例数量,避免资源浪费,全局访问点简化资源访问

避免频繁创建销毁对象,减少全局变量污染

缺点:

违反单一职责原则(同时管理自身和业务),且单元测试困难(全局状态难以隔离)

可能隐藏类间依赖关系,多线程环境需要特殊处理

  • 知识图解

image

  • 使用场景

比如要实现下列功能时

日志管理器(Logger)

数据库连接池

配置读取器(配置文件只读一次)

驱动设备控制器(如串口、打印机)

游戏中的全局控制器(音效、UI管理)

Last Updated: 3/10/2026, 6:08:48 PM

← this指针的原理 STL容器了解哪些 →

评论

验证登录状态...

侧边栏
夜间
卡码简历
代码随想录
卡码投递表🔥
2026群
添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记
鼓励/支持/赞赏Carl
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪