靜態建構函數語法與特徵
ref class SimpleClass {
public:
static SimpleClass() { // 無參數、無存取修飾符
// 型別級初始化邏輯
Console::WriteLine("Type initialized");
}
};
七大核心規則
- 無參數、無修飾符: 由 CLR 自動調用,
public/private 無意義。
- 觸發時機: 建立第一個實例 或 存取任何靜態成員 之前,CLR 保證執行一次。
- 不可直接調用: 無法在代碼中顯式呼叫,時機完全由 CLR 控制。
- 每類別僅一個: 不可多載。
- 與無參實例建構函數共存: 簽名雖同但層級不同 (型別 vs 實例),不衝突。
- 最多執行一次: AppDomain 內線程安全初始化,雙重檢查鎖模式由 CLR 內建。
- 不可繼承: 派生類別有自己的靜態建構函數,基類靜態建構函數在派生類首次使用前執行。
編譯器自動生成場景
若類別包含帶初始化運算式的靜態欄位,且無顯式靜態建構函數,編譯器自動生成預設靜態建構函數執行這些初始化。
ref class Config {
public:
static int MaxConnections = 100; // 編譯器生成 .cctor 設定 100
static String^ DefaultPath = "C:\\Data"; // 生成 .cctor 分配字串
};
靜態建構函數 vs 實例建構函數
| 特性 | 靜態建構函數 (.cctor) | 實例建構函數 (.ctor) |
| 調用者 | CLR (自動) | 程式碼 (new/gcnew) |
| 執行次數 | 每 AppDomain 一次 | 每實例一次 |
| 存取成員 | 僅靜態欄位/屬性 | 實例與靜態皆可 |
| 參數 | 無 | 可有參數 |
| 異常處理 | 失敗導致 TypeInitializationException,型別不可用 | 失敗僅影響當前實例建立 |
最佳實踐與陷阱
- 避免複雜邏輯/阻塞呼叫: 靜態建構函數死鎖將凍結整個型別。
- 靜態欄位初始化順序: 同類別內按原始碼順序;跨類別依賴靜態欄位極危險 (順序不定),改用靜態屬性延遲初始化 模式。
- 泛型類別: 每個封閉構造類別 (
List<int>, List<string>) 獨立執行靜態建構函數。
延遲初始化模式 (推薦替代複雜 .cctor)
ref class Settings {
private:
static Dictionary<String^, String^>^ _cache;
public:
static property Dictionary<String^, String^>^ Cache {
Dictionary<String^, String^>^ get() {
if (_cache == nullptr) {
_cache = gcnew Dictionary<String^, String^>();
// 載入設定...
}
return _cache;
}
}
};
- 上一篇文章: Visual Studio .NET 中 C++ 語言擴展演進:雙下劃線關鍵字、CLR 整合與決定性解構模式
- 下一篇文章: C++ 面向物件核心特性全景解析:封裝、繼承、多態、友元、運算子重載與動態綁定
Copyright ©
程式碼之家 All Rights Reserved