专业编程基础技术教程

网站首页 > 基础教程 正文

C++11魔法静态变量magic static c++中静态变量的使用

ccvgpt 2024-10-12 13:56:29 基础教程 5 ℃

魔法静态变量是C++11的核心语言功能特性,最早在GCC2.3、CLang2.9、MSVC19.0等编译器得到支持,相关标准提案为:N2660-Dynamic Initialization and Destruction with Concurrency (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm)。


C++11魔法静态变量magic static c++中静态变量的使用

其在C++程序中的一个重要体现为单例模式。在魔法静态变量特性提出以前,设计单例模式一般是采用饿汉式或懒汉式,需要考虑多线程竞争的问题(需要引入互斥锁)。C++11之后,只需要定义一个静态局部变量即可,该变量保证只初始化一次(即使在多线程环境中)。如:

class SingleInstance
{
public:
	static SingleInstance& GetInstance()
	{
		static SingleInstance instance;
		return instance;
	}
	
	// 或者
	static SingleInstance* GetInstanceP()
	{
		static SingleInstance instance;
		return &instance;
	}
};

下文是对C++11起静态局部变量的说明,在此之前,先了解一下静态存储期。

静态存储期

这类对象的存储在程序开始时分配,并在程序结束时解分配。这类对象只存在一个实例。所有在命名空间(包含全局命名空间)作用域声明的对象,加上声明带有static或extern的对象均拥有此存储期。

静态局部变量

在块作用域声明且带有static或thread_local说明符的变量拥有静态或线程存储期,但在控制首次经过它的声明时才会被初始化(除非它被零初始化或常量初始化,这可以在首次进入块之前进行)。在其后所有的调用中,声明都会被跳过。

如果初始化抛出异常,那么不认为变量被初始化,且控制下次经过该声明时将再次尝试初始化。

如果初始化递归地进入正在初始化的变量的块,那么行为未定义。

如果多个线程试图同时初始化同一静态局部变量,那么初始化严格发生一次(类似的行为也可以对任意函数以std::call_once来实现)。注意:此功能特性的通常实现为使用双检查锁定模式的变体,这使得对已初始化的局部静态变量检查的运行时开销减少为单次非原子的布尔比较。

块作用域静态变量在初始化已成功的情况下,其析构函数在程序退出时被调用。

在相同内联函数(可以是隐式内联)的所有定义中,函数局部的静态对象均指代在一个翻译单元中定义的同一对象,只要函数拥有外部链接。

最近发表
标签列表