【C++】extern,static inline再次总结

1. extern声明全局变量

extern用在声明变量处,不可赋初值,不分配内存。告诉链接器去别的目标文件找符号。

该变量定义在另一个文件,定义处不加extern。
使用该变量的地方,在使用处之前使用extern表明使用,链接器去其他文件找。

//a.h
extern int g_a;  //声明
//a.cpp
int g_a = 10;  //定义,外部链接

//b.cpp
extern int g_a;  //使用前声明

void func()
{
  g_a = 5;  //使用
}

2. inline修饰变量

作用于静态成员

直接在.h文件的类定义中定义静态成员,而不需要在.cpp文件中通过int A::a=10去定义了

class A
{
  static int a = 10;  //非法
}

class A
{
  inline static int a = 10;  //合法
}

作用于非成员变量

  • 全局命名空间:
//header.hpp
int a = 10;  //全局变量,全局命名空间。多个.cpp均引入该文件时,报重定义错误

inline int a = 10;  //解决重定义问题
  • 具名命名空间:
    和全局命名空间一样的
//header.hpp
namespace qqq
{
  int a = 10;  //同上,只不过访问时需要指明具名命名空间
}

namespace qqq
{
  inline int a = 10;
}

3. static inline修饰全局变量/命名空间内变量

“只在当前翻译单元可见”,每个翻译单元都会生成自己的独立实体。也就是:每个引入static inline头文件的cpp文件都会有自己独立的该变量
static:作用于命名空间/全局变量时,表示:内部链接(每个翻译单元各有一份)。不用static修饰时默认是外部链接。
inline:“允许在多个翻译单元中出现重复定义”,但不会改变链接属性。

而所有cpp文件共用1个全局变量counter,要求:外部链接。

//所有cpp文件共用1个counter
// header.hpp
#pragma once
extern int counter;  //声明

// globals.cpp
#include "header.hpp"
int counter = 0;  //定义,全局变量默认外部链接。

4. 外部链接与内部链接

一句话先说明

  • 外部链接(external linkage):名字在整个程序(所有翻译单元)中唯一,链接时可跨文件访问。
  • 内部链接(internal linkage):名字仅在当前翻译单元内部可见,别的单元看不见、也链接不到。

1. 产生规则速查表

出现位置 默认链接 如何改成内部链接 备注
命名空间/全局变量 外部 static int g;→外部,static int g;→内部
普通函数 外部 static void f(); vs static void f();
类的静态成员 外部 无法改成内部 始终外部
匿名命名空间 内部 namespace { int x; }
const 全局变量 内部(C++规则) extern 可显式外部 const int c = 1; 默认为内部

2. 代码对比

// a.cpp
int  globalA = 0;        // 外部链接
static int globalB = 0;  // 内部链接,只能在 a.cpp 内使用

// b.cpp
extern int globalA;      // 合法,链接到 a.cpp 的那一份
// extern int globalB;   // 非法,链接器找不到

3. 链接阶段发生了什么

  • 外部链接符号(如 globalA)在所有目标文件中只有一份;
  • 内部链接符号(如 globalB)在每个目标文件各有一份,名字互不干扰。

4. 常见误区

误区 正解
“全局变量默认就是 extern” 变量本身默认外部链接,但 extern 只是 声明语法,不是变量属性。
const int x = 1; 默认外部 错!默认内部链接(C++规则),需要 extern const int x = 1; 才能外部。
inline 会改变链接 不会,只影响“可重复定义”规则,不改变 static/extern 的链接属性。

5. 记忆口诀

全局/函数默认外部,要内部加 static
匿名命名空间天然内部;
const 全局默认内部,想外部加 extern

posted @ 2025-08-20 17:27  仰望星河Leon  阅读(41)  评论(0)    收藏  举报