聲明可多次,定義全局唯一(ODR 原則)。頭文件供多 .cpp 包含,故頭文件中只能放聲明、inline 定義、模板定義、const 整型常量定義;非 inline 函數定義、非常量變量定義必須放在 .cpp。
| 實體 | .h 中定義 | .cpp 中定義 | 不同 .cpp 可重名 | 特殊說明 |
|---|---|---|---|---|
| 普通函數 | ❌ 重定義錯誤 | ✅ | ❌ | 僅在 .h 聲明 |
| inline 函數 | ✅ 必須 | ✅ | ✅ | 保證所有編譯單元定義一致 |
| typedef | ✅ | ✅ | ✅ | 無實體,僅類型別名 |
| 全局變量 | ❌ 重定義 | ✅ | ❌ | .h 用 extern 聲明 |
| const 變量 (常量表達式初始化) | ✅ | ✅ | ✅ | 編譯期常量,內部鏈接 |
| const 變量 (非常量表達式) | ❌ | ✅ | ✅ | .h extern const 聲明 |
| static 全局變量/函數 | ✅ (但每 .cpp 獨立副本) | ✅ | ✅ | 內部鏈接,通常放 .cpp |
| 類定義 | ✅ | ✅ | ✅ | 類名可同,但定義應一致 |
| 類內成員函數定義 | ✅ (隱式 inline) | ✅ (需 inline 或放 .cpp) | — | 類外定義加 inline 否則重定義 |
| 類靜態數據成員 | ❌ (僅聲明) | ✅ (必須定義) | — | 非常量靜態成員必須 .cpp 定義 |
| 類靜態 const 整型成員 | ✅ 可類內初始化 | ✅ (可選) | — | C++11 允許非整型類內初始化 |
| 模板 | ✅ 聲明+定義必須同文件 | ❌ | — | 不支持分離編譯 (export 除外) |
// a.h
void show() { cout << "hi"; } // 多 .cpp include → LNK2005 重定義
// a.h
#pragma once
void show();
// a.cpp
#include "a.h"
void show() { cout << "hi"; }
// a.h
inline void show() { cout << "hi"; } // 或類內定義自動 inline
// a.h const int MAXN = 100; // 編譯期常量,每 .cpp 獨立副本,無重定義 const double PI = 3.14; // 非常量表達式?視編譯器,建議 .cpp 定義 + extern
int x = 0;。constexpr 變量隱含 const 且編譯期求值,可放 .h 定義。