在托管堆上分配對象實例,似乎是使用托管擴展C++、#、J#、VB.NET程序員的唯一方法,而使用本地C++的程序員,不但可以在堆上分配內存,甚至更慣於使用基於堆棧的對象實例。
現在回顧一下以前定義的Point引用類,再來看一下以下變量定義:
Point p1, p2(3,4);
從本地C++的角度來說,p1與p2應為基於堆棧的引用類Point實例,哪怕是從一般性的角度來看,它們也是。P1由默認的構造函數初始化,而p2由接受x與y坐標的構造函數初始化。從實現上來看,Point是自包含類型的(也就是說,它不包含任何指針或句柄),然而,作為一個引用類的實例,它仍處於CLI運行時的掌控之下,且在必要時,會被垃圾回收--正因為此,所以不能定義一個引用類的靜態或全局實例。
同時,也不能將sizeof應用於指明是引用類實例的表達式,因為sizeof是在編譯時進行計算的,而Point對象的大小要直到運行時才能確定;但是,可將sizeof應用於句柄,因為它的大小在編譯時就已經確定了。
另外,還不能定義一個基於堆棧的CLI數組實例。
跟蹤引用
本地C++可通過&來定義一個對象的別名,例如,對任意本地類N,可編寫如下代碼:
N n1;
N& n2 = n1;
引用必須在定義時進行初始化,且在整個生命期中,它們都鎖定於引用同一對象,也就是說,它的值不會改變。引用一個引用類的實例與引用一個本地類基本一致,只不過語法不同而已。
在程序執行期間,引用類的實例會在內存中"移動",所以,需要對它們進行跟蹤,而本地指針與引用卻不能夠勝任這項工作(尤其指不能對一個引用類的實例使用取地址符&),因此,C++/CLI對應地提供了句柄及用於跟蹤的引用--在此簡稱為跟蹤引用(Tracking References),例如,你可以定義一個跟蹤引用p3,以追蹤對象p2: