知识准备:
类的静态成员变量必须得在类外初始化
由于静态变量在编译期间必须定义(分配空间),静态成员变量在类中仅仅是声明,没有定义,所以要在类的外面定义,实际上是给静态成员变量分配内存。类内的静态成员变量若没有类的外面定义,是没有分配内存的。而类内的静态函数编译完就分配内存,就可以直接调用;类内的静态函数中的静态局部变量,是在第一次调用函数的时候初始化。
但在C和C++中静态局部变量的初始化节点又有点不太一样。在C中,初始化发生在代码执行之前,编译阶段分配好内存之后,就会进行初始化,所以我们看到在C语言中无法使用变量对静态局部变量进行初始化,在程序运行结束,变量所处的全局内存会被全部回收。而在C++中,初始化时在执行相关代码时才会进行初始化,主要是由于C++引入对象后,要进行初始化必须执行相应构造函数和析构函数,在构造函数或析构函数中经常会需要进行某些程序中需要进行的特定操作,并非简单地分配内存。所以C++标准定为全局或静态对象是有首次用到时才会进行构造,并通过atexit()来管理。在程序结束,按照构造顺序反方向进行逐个析构。所以在C++中是可以使用变量对静态局部变量进行初始化的。
能在类中初始化的成员只有一种,那就是静态整型常量成员。
下面代码实现了三种常见的单例模式
#include <iostream>
#include "pthread.h"
using namespace std;
pthread_mutex_t g_single_lock;
class Single
{
public:
//函数内的局部静态变量在编译时已经分配空间,在第一次函数跑到这里时初始化,之后不再初始化
//多线程访问时,若不加锁,可能会出现多次初始化的问题,但是地址是不会变的
static Single *get_instance1()
{
static Single instance;
return &instance;
}
static Single *get_instance2()
{
//double check 防止多线程每次都要加锁,影响性能
if(NULL == m_instance)
{
pthread_mutex_lock(&g_single_lock);
if(NULL == m_instance)
{
m_instance = new Single();
}
pthread_mutex_unlock(&g_single_lock);
return</