ODR、链接与头文件
更新时间:2026-10-01。把跨文件的声明/定义、重复符号讲透,是排查链接错误的基本功(C 侧也有对应基础)。
一、声明 vs 定义
多个 TU 各自编译,链接时合并符号;非 inline 的函数/对象若在两个 TU 各有一份外部链接定义,即违反 ODR、报重复定义(如 LNK2005)。
二、解决手段
- 只声明放头,定义放唯一一个 .cpp。
inline函数 / C++17inline变量允许各 TU 保留相同定义、链接器合并(static constexpr成员常配inline)。- 匿名命名空间/
static给内部链接,使各 TU 私有副本(可能造成代码膨胀)。

常见坑
- 全局变量在头定义被多包含。
- 匿名命名空间里定义本想共享的变量,各 TU 不互通。
- 各 TU 看到不一致定义导致 ODR 违规(常静默出错)。
小结
总结
C++ 编译模型里声明可重复、而定义受 ODR(一处定义规则)约束:非 inline 的函数/对象若在两个翻译单元各有一份外部链接定义,链接时即报重复符号(如 LNK2005);根治手段是"声明放头、定义放唯一一个 .cpp",或用 inline 函数 / C++17 inline 变量允许各 TU 保留相同定义由链接器合并(static constexpr 成员常配 inline),用匿名命名空间或 static 给内部链接则得到各 TU 私有的副本(可能代码膨胀);最隐蔽的坑是各 TU 看到不一致的定义导致静默 ODR 违规,C++ modules 是未来的改善方向。