• C++:static:谈一谈static关键字


    C++ static关键词有三种完全不同的用途

    1. 表示一个静态存储期的变量,且具有 internal linkage (俗称:static 变量)
    2. 表示一个静态存储期的变量,但是只在一个局部作用域可见,保证仅初始化一次(俗称:static local变量)
    3. 表示一个 class 的静态成员,整个class共享一份,不绑定到任何 instance (俗称:static member变量)

    static 变量

        通常他们在main函数之前初始化,存活到 main函数结束

    static int a ;  // static 变量

    static local 变量 

       在一个函数体(严格的说是 block scope) 内部,用static 变量就是 static local 变量。

    这类变量一般在第一次运行到这段代码就初始化(付出的代价就是每次运行到这里就要检查一遍是否被 初始化)

    1. void func(){
    2. static int a ; // static local 变量
    3. }

    static member变量

    1. // A.h
    2. class A
    3. {
    4. static int a ;
    5. }
    1. 很明显 符号 a 的地位类似于全局变量,但是问题也随之出现了,当这个头文件被多个翻译单元 include时候,这个符号 a 应该放在哪个文件里比较合适了?
    2. 而且如果有多个文件 include “a.h”但是总不能每个翻译单元都生成一个符号把  ??

    于是C++设计者想出了这么一个方案,再加一条语句用来专门生成符号,顺便初始化。

    1. // A.h
    2. class A {
    3. static int a; // 不生成符号
    4. }
    5. // A.cpp
    6. include "A.h"
    7. int A::a; // 生成一个符号,并初始化

    很显然,变量a 的初始化是在类外进行的,头文件 类内不能初始化,如果我们一定要在类内初始化了 ??我们可以这样做

    1. // A.h
    2. class A
    3. {
    4. static const int a = 0 ; // 不生成符号,但是在编译时可以读取 a的值
    5. }
    6. // A.cpp
    7. #include “A.h”
    8. int A::a; // 在类外提供一个符号,让其在链接时可以找到符号。

    那么如何避免:总不能让每个翻译单元都有一个符号把了 ??

    C++17引入了 inline修饰符,添加了 inline修饰符后,就可以每个翻译单元生成一个符号,然后链接器去链接的时候,选择其中一个

    1. // A.h
    2. class A {
    3. static inline int a = 2; // 生成符号,可以取地址 , 并且支持类内初始化。
    4. }

    然后C++17以后,constexpr 的 static member变量默认 inline ,所以你可以这样写

    1. // A.h
    2. class A {
    3. static constexpr int a = 3; //生成符号,可以取地址,并且支持初始化
    4. }

     

  • 相关阅读:
    【makedown使用介绍】
    使用Spring Cache实现广告缓存并基于RabbitMQ实现双写一致
    代码随想录二刷第二天(Python)
    一文讲透为Power Automate for Desktop (PAD) 实现自定义模块 - 附完整代码
    【数据结构笔记04】数据结构之栈的顺序表示和实现(顺序栈)
    PS怎么给GIF文字上加图片?
    K8sGPT,基于 AI 的云原生终极工具
    面向对象编程(二)
    PCB表面缺陷检测项目 | 轻量化PCB表面缺陷检测算法实现
    【Java 基础语法】Java 的文件操作
  • 原文地址:https://blog.csdn.net/u013620306/article/details/127931847