Skip to content

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 有三种用法

  1. static 成员变量
  2. static 成员函数
  3. 成员函数中的 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;}
};