在C++中,?頭文件(.h/.hpp)?? 的主要作用是聲明接口和共享代碼,但如果不規范使用,會導致編譯或鏈接錯誤。以下是詳細總結:
一、頭文件中可以做的事情
1.1 聲明
- 函數聲明(無需inline)
// utils.h
void print(); // 聲明
- 類或者結構體聲明
class MyClass {
public:void foo(); // 成員函數聲明
};
- 外部變量聲明(用extern)
如果不想用extern,可以使用C++17支持的內聯全局變量
extern int globalVar; // 聲明,定義在.cpp中
1.2 定義
- 內聯函數的定義
inline int add(int a, int b) { return a + b; } // 解決ODR問題
- 類或者結構體成員函數定義
class Vector {
public:float x, y;float length() const { return std::sqrt(x*x + y*y); } // 隱式inline
};
- 模板定義
template<typename T>
T max(T a, T b) { return (a > b) ? a : b; } // 模板必須完整定義在頭文件
- 常量表達式(C++11)
constexpr float PI = 3.1415926f; // 內部鏈接,每個編譯單元獨立副本
- C++17內聯變量
inline int globalConfig = 42; // 允許頭文件中定義全局變量
1.3 其他
- 宏定義?(謹慎使用)
- 類型別名(using 或者 typedef)
- 命名空間
二、頭文件中不可以做的事情
1.1 普通函數定義
原因?:違反ODR規則,多個編譯單元生成相同符號,鏈接沖突。
// utils.h
void print() { std::cout << "Hello"; } // ? 多個.cpp包含時鏈接錯誤
1.2 非內聯全局變量定義
int globalVar = 42; // ? 多個.cpp包含時鏈接錯誤
1.3 靜態全局變量
問題?:每個包含該頭文件的.cpp會生成獨立的 localVar,浪費內存。
static int localVar = 0; // ?? 每個編譯單元獨立副本,可能不符合預期
1.4 復雜代碼邏輯?
避免在頭文件中寫長函數或復雜邏輯?(如文件操作、動態內存分配)。
?原因?:增加編譯時間,代碼膨脹。