在.NET平台下开发,unsafe代码依然很重要,因为现有的很多代码都是iso-c++的,涉及到很多指针操作和运算。如果将其都转化为托管代码,工作量非常大。因此在托管代码中使用unsafe类型是非常重要的手段。本文在《Pro Visual C++ CLI and the dot.NET 2.0 Platform》的基础上,针对非托管类、值类和引用类的相互调用问题进行了总结。
class Class {};
ref class RefClass {};
value class ValueClass {};
下表显示的是class、Value class、Ref class的类成员中是否可以有左侧不同类型的对象。
包含关系
|
Class
|
Value class
|
Ref class
|
Class c;
|
√
|
|
|
Class* pc;
|
√
|
√
|
√
|
ValueClass vc;
|
√
|
√
|
√
|
ValueClass *pvc;
|
√
|
√
|
√
|
ValueClass ^hvc;
|
|
√
|
√
|
RefClass rc;
|
|
|
√
|
RefClass ^hrc;
|
?
|
√
|
√
|
1 值类型不能包含引用类型对象,但是可以有引用类型句柄。因为如果值类型可以包含引用类型对象,建立值类型对象时,就决定了在托管堆中建立值类型对象,这是不符合值类型定义的。
2 引用类型和值类型可以包含非托管类的指针:






























这意味着可以在托管代码中可以使用现有的非托管类。
3 “?”表示在非托管类中虽然不能包含托管类句柄,但是可以包含
gcroot< RefClass ^> mclass;
如下面代码:







































下表显示的是class、Value class、Ref class是否可以继承自左侧不同类型。
继承关系
|
Class
|
Value class
|
Ref class
|
Class
|
√
|
|
|
ValueClass
|
|
|
|
RefClass
|
|
|
√
|
值类型不能继承自其他类型,只能继承自接口。
引用类型也不能继承自值类型,因为继承是Is-A关系。引用类型和值类型只有通过装箱/拆箱操作进行相互转换。
非托管类只能继承自非托管类。
总结自《Pro Visual C++ CLI and the dot.NET 2.0 Platform》p812