c++中的static
static
- static 变量的生命周期从初始化起一直持续到程序执行结束
- static 变量存放在数据区,分为已初始化的全局变量区(data 段)和未初始化的全局变量区(bss 段)
- static定义的全局变量和函数只在当前文件可见
- static变量初始化时机
- static全局变量在main函数执行之前初始化
- 函数内部static变量在第一次访问该变量时初始化
static全局变量和extern全局变量
相似之处:
- 不管是哪种全局变量,都会默认初始化
区别:
- 不能同时指定extern和static
- extern定义的全局变量作用域可以扩展到整个程序,只要在使用的地方用extern声明即可。
- static定义的全局变量只在当前文件可见
下面是使用extern的例子
// A.cpp
//以下三种写法是都定义的是extern全局变量
extern int A = 5;
int B = 6;
int C; //默认初始化为0
// B.cpp
//声明
extern int A;
extern int B;
extern int C;
类中的 static
类中的 static 有三种用法
- static 成员变量
- static 成员函数
- 成员函数中的 static 变量
static 成员变量
- 不包含在任何对象中
- 可以是 public,也可以是 private
- 必须在类外部定义和初始化静态成员
- static 关键字只能出现在类内部的声明中,外部的定义不加 static
- 如果静态成员是字面量类型的 constexpr,就可以在类内定义和初始化。
- 使用作用域运算符直接访问
//ca.h
class CA
{
public:
static int a; //类内static声明
};
//ca.cpp
#include "algo.h"
int CA::a = 5; //类外定义和初始化
static 成员函数
- 不包含 this 指针,不能加 const 限定符
- 使用作用域运算符直接访问
成员函数中的 static 中的成员变量
可以使用这个特性来实现 C++11 的单例模式,并且是线程安全的
# pragma once
# include <iostream>
class Demo_A
{
public:
static Demo_A & getDemoA()
{
//保证控制流第一次进入函数时触发初始化
static Demo_A onlyOne;
std::cout<<"get demo A."<<std::endl;
return onlyOne;
}
//禁用拷贝和移动
Demo_A(const Demo_A &) = delete; //拷贝构造
Demo_A & operator=(const Demo_A &) = delete; //拷贝赋值
Demo_A(Demo_A &&) = delete; //移动构造
Demo_A & operator=(Demo_A &&) = delete; //移动赋值
private:
Demo_A(){std::cout<<"demo_a construct."<<std::endl;}
};