Colderleo's blog Colderleo's blog
首页
Linux
C++
Python
前端
工具软件
mysql
索引
关于
GitHub (opens new window)

Colder Leo

热爱代码的打工人
首页
Linux
C++
Python
前端
工具软件
mysql
索引
关于
GitHub (opens new window)
  • bug定位的一些情形
  • c++性能调优,可能的情况
  • total-编程知识点集锦
  • hpc_common.hpp
  • memory order 内存模型
  • 类型推导之auto-template-decltype
  • 完美转发forward源码分析
  • 左值和右值,右值引用、重载 std-move,引用折叠
  • cmake用法
  • alignas、alignof、sizeof实现内存对齐分配
  • 通过宏定义控制debug打印
  • 程序耗时性能测试
  • 线程池开源项目阅读
  • C++类中包含没有默认构造函数的成员
  • C++可变参数模板
  • C++属性继承 public protected private
  • C++智能指针
  • C++导出so的方法,以及extern C 注意事项
  • 四种spin lock
  • condition_variable和unique_lock
  • dpdk、kernel bypass
  • 智能网卡solarflare、Mellanox、X10等
  • 汇编寄存器和常见指令
  • c++ 类的静态成员变量未定义
  • C++获取类成员函数地址
  • preload示例
  • C++异常安全和RAII
  • C++11单例模式
    • Meyer's Singleton 局部静态变量
    • 补充:C++中static对象的初始化
      • non-local static对象(函数外)
      • local static 对象(函数内)
  • C++歪门邪道
  • boost-program-option用法
  • c++17通过模板获取类成员的个数
  • 通过模板实现结构体成员拷贝-按成员名匹配
  • STL学习路径
  • boost库安装使用方法
  • C++文件读写
  • linux下socket通信demo,server和client
  • makefile写法
  • RxCpp
  • C++
gaoliu
2022-06-03
目录

C++11单例模式

# Meyer's Singleton 局部静态变量

参考: https://blog.csdn.net/lgfun/article/details/105810039 (opens new window)

函数内部的静态局部变量的初始化, 是在函数第一次调用时执行; 在之后的调用中不会对其初始化。

C++11规定, 静态局部变量在多线程情况下初始化,由编译器保证其是线程安全的。因此可以借用此特性得到一种目前最安全便捷的单例模式,即在函数内部定义static局部变量作为单例。这就是Effective C++ 中提出的 Meyers' Singleton

这样,只有当第一次访问getInstance()方法时才创建实例。C++0x之后该实现是线程安全的,C++0x之前仍需加锁。

class Singleton
{
private:
	Singleton() { };
	~Singleton() { };
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);
public:
	static Singleton& getInstance() 
  {
		static Singleton instance;
		return instance;
	}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14

验证:

#include <iostream>
#include <thread>

class Singleton {
    private:
        Singleton() {
            std::cout << "构造函数" << std::endl;
        };
        ~Singleton() {
            std::cout << "析构函数" << std::endl;
        };
    public:
        Singleton(const Singleton&)            = delete;
        Singleton& operator=(const Singleton&) = delete;
    public:
        static Singleton& getInstance() {
            //返回local static的引用
            static Singleton instance;
            return instance;
        }
};

int main(void)
{
    for (int i = 0; i < 10; ++i) {
        std::thread([]() {
            std::cout << &Singleton::getInstance() << std::endl;
        }).join();
    }
    std::cout << &Singleton::getInstance() << std::endl;
    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
31
32

# 补充:C++中static对象的初始化

# non-local static对象(函数外)

C++规定,non-local static 对象的初始化发生在main函数执行之前,也即main函数之前的单线程启动阶段,所以不存在线程安全问题。但C++没有规定多个non-local static 对象的初始化顺序,尤其是来自多个编译单元的non-local static对象,他们的初始化顺序是随机的。

# local static 对象(函数内)

对于local static 对象,其初始化发生在控制流第一次执行到该对象的初始化语句时。多个线程的控制流可能同时到达其初始化语句。

在C++11之前,在多线程环境下local static对象的初始化并不是线程安全的。具体表现就是:如果一个线程正在执行local static对象的初始化语句但还没有完成初始化,此时若其它线程也执行到该语句,那么这个线程会认为自己是第一次执行该语句并进入该local static对象的构造函数中。这会造成这个local static对象的重复构造,进而产生内存泄露问题。所以,local static对象在多线程环境下的重复构造问题是需要解决的。

而C++11则在语言规范中解决了这个问题。C++11规定,在一个线程开始local static 对象的初始化后到完成初始化前,其他线程执行到这个local static对象的初始化语句就会等待,直到该local static 对象初始化完成。

编辑 (opens new window)
上次更新: 2023/05/07, 17:27:54
C++异常安全和RAII
C++歪门邪道

← C++异常安全和RAII C++歪门邪道→

最近更新
01
通过模板实现结构体成员拷贝-按成员名匹配
05-07
02
c++17通过模板获取类成员的个数
05-01
03
avx-sse切换惩罚
04-30
更多文章>
Theme by Vdoing | Copyright © 2019-2023 Colder Leo | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×