原生 C++ 提供記憶體直接控制 (堆疊/CRT 堆/new/delete),高效但易洩漏。CLR GC 提供單一程式模型、跨語言互操作、配置效率優化。托管 C++ 用 new 產生 newobj IL 指令配置托管堆,但不能 delete,語義矛盾證明指標不適合表達參考型別。
C++/CLI 記憶體管理無新機制,核心創新在資源管理。
Stroustrup 的 RAII:建構函式取得資源,解構函式釋放。CLR 無解構函式概念,改用 IDisposable.Dispose(),需手動呼叫。C# 用 try-finally/using 保證釋放,易忘寫導致靜默錯誤。
using (SqlConnection conn = new SqlConnection(...)) {
using (SqlDataReader reader = cmd.ExecuteReader()) {
while (reader.Read()) Console.WriteLine(reader.GetString(0));
}
}
Using<SqlConnection> conn(new SqlConnection(...));
Using<SqlDataReader> reader(cmd->ExecuteReader());
C++/CLI 承認 Dispose 重要性,在參考型別中將其視為邏輯解構函式:
ref class Derived : Base {
~Derived() { /* 釋放托管與非托管資源 */ } // 實作 IDisposable::Dispose
!Derived() { /* 僅釋放非托管資源 */ } // 實作 Finalize
};
Dispose 實作 (含 GC::SuppressFinalize)。Dispose 或繼承 IDisposable (編譯錯誤)。delete handle 呼叫 Dispose,記憶體交給 GC。允許參考型別使用堆疊語法,編譯器注入智慧指標,底層仍在托管堆配置:
Derived d; // 堆疊宣告
d.SomeMethod(); // 使用
// 離開作用域自動呼叫 ~Derived() (Dispose),GC 稍後回收記憶體
// C++/CLI 堆疊語義
SqlConnection conn("Database=master; Integrated Security=sspi");
SqlCommand^ cmd = conn.CreateCommand();
cmd->CommandText = "sp_databases";
cmd->CommandType = CommandType::StoredProcedure;
conn.Open();
SqlDataReader reader(cmd->ExecuteReader());
while (reader.Read()) Console::WriteLine(reader.GetString(0));
// 自動釋放連線、讀取器資源
無需 using 區塊、try-finally、delete,純粹 C++ 風格,資源確定性釋放。