經典 C++ 面試題:分析結構體 A 中 static int x 與 int y 的關係,以及實例化物件 a(4,7) 後,a.x、a.y、A::x、A::y 之間的等價關係。
struct A {
static int x; // 靜態成員:屬於類別,全程式僅一份
int y; // 實例成員:屬於物件,每個物件各有一份
public:
operator int() { return x - y; }
A operator++(int) { return A(x++, y++); }
A(int x = ::x + 2, int y = ::y + 3) { A::x = x; A::y = y; }
int& h(int& x);
};
| 特性 | static int x (靜態成員) | int y (實例成員) |
|---|---|---|
| 所屬 | 類別 A | 具體物件 (如 a, b, c) |
| 記憶體 | 全域/靜態區,程式啟動分配,僅一份 | 堆疊/堆區,每建立物件分配一份 |
| 存取方式 | A::x (類別名)、a.x (物件名) | a.y (僅能透過物件) |
| 共享性 | 所有物件共享同一記憶體 | 各物件獨立記憶體,值互不干擾 |
| 生命週期 | 程式開始→程式結束 | 物件建立→物件銷毀 |
| 表達式 | 含義 | 等價關係 |
|---|---|---|
a.x | 物件存取靜態成員 | = A::x = b.x = c.x |
A::x | 類別存取靜態成員 | = a.x = b.x = c.x |
a.y | 物件存取實例成員 | ≠ b.y ≠ c.y (獨立) |
A::y | **編譯錯誤** | 不存在 (靜態無法存取非靜態) |
// 記憶體佈局概念圖
全域/靜態區:
+------------------+
| A::x (4 bytes) | ← 唯一一份,所有 A 物件共享
+------------------+
堆疊/堆區 (物件 a):
+------------------+
| a.y (4 bytes) | ← a 專屬
+------------------+
堆疊/堆區 (物件 b):
+------------------+
| b.y (4 bytes) | ← b 專屬,與 a.y 完全無關
+------------------+
static 成員屬於類別,實例成員屬於物件。這是 C++ 物件模型的基石:
x 是「類別的 x」,不屬於任何物件,所有物件共享y 是「物件的 y」,每個物件擁有獨立副本A::y 是語法錯誤,切勿混淆理解這點,對掌握 C++ 記憶體模型、避免靜態成員競態條件、設計單例模式等都至關重要。