值类型 VS 引用类型 (C++/CLI)

 

    值类型自动继承自 System::ValueType, 引用类型自动继承自 System::Object,

 

虽然S ystem::ValueType 也继承自 System::Object, 但二者仍有不少差别。

   

 1. 值类型分配在栈上,引用类型分配在托管堆上。

 

 2. 值类型不能作为另一个类型的基类,但可以实现接口。

 

 3. 值类型不可以定义析构器,也不可以定义终结器。所以不要在值类型里面引用

 

    非托管资源,不要为值类型实现 Dispose 模式。

 

 4. 值类型默认实现拷贝构造函数与赋值重载操作符,引用类型默认不实现拷贝构

 

    造函数与赋值重载操作符,这个设计使得使用栈对象时非常不方便。

   

 5. 值类型不可以自定义无参构造函数,拷贝构造函数及赋值重载操作符,只能使

 

    用默认的(拷贝及赋值内部是以逐位复制的形式实现的)。

   

 6. 对于值类型来说,可以定义为全局变量,也可以定义为全局静态实例,引用类型却

 

    不可以这么做。值类型和引用类型都不能定义为全局追踪句柄及全局静态追踪

   

    句柄。二者都可以定义为静态实例字段和静态追踪句柄字段。

 

 7. 值类型可以包含另一个值类型,可以包含在一个引用类型中,可以包含

 

    一个引用类型的追踪句柄,但不可以直接包含一个引用类型,下面的代

   

    码不能通过编译:

   

    value class MyRefClass

    {

    public:

        Object Data;

    };

   

    而要改成下面的形式:

   

    value class MyRefClass

    {

    public:

        Object^ Data;

    };

   

 8. 值类型和引用类型都不能包含本地类型(包括本地C++ 数组及本地类,本地结构等),

 

    而应该使用本地指针。

 

 9. 和引用类型一样,值类型不能包含在自身类型中。但可以包含自身类型的

 

    追踪句柄。下面的代码不能通过编译:

  

    value class Node

    {

    public:

        Node Next;

    };

   

    改为下面的形式可以通过编译:

   

    value class Node

    {

    public:

        Node^ Next;

    };

   

 10.引用类型的实例构造函数或成员函数中,this 为追踪句柄,值类型中则为

 

    内部指针。

  

 11.值类型的追踪句柄不可以作为泛型的 typename, 而只能使用值类型本身,

 

    下面的代码不能通过编译:

   

    using namespace System::Collections::Generic;

 

    value class Data

    {

    };

 

    int main() {

        List<Data^>^ list = gcnew List<Data^>();

       

        return 0;

    }

   

    引用类型不可直接作为泛型的 typename, 而只能使用追踪句柄,下面的

   

    代码不能通过编译:

   

    using namespace System::Collections::Generic;

 

    ref class Data

    {

    };

 

    int main() {

        List<Data>^ list = gcnew List<Data>();

       

        return 0;

    }

   

    如果需要将一个值类型的追踪句柄放在一个集合内,只能对其装箱,可以这样

   

    做:

   

    using namespace System::Collections;

 

    value class Data

    {

    };

 

    int main() {

        ArrayList^ list = gcnew ArrayList();

        Data^ data = gcnew Data();

        list->Add(data);

       

        return 0;

    }

   

    或者这样做:

   

    using namespace System;

    using namespace System::Collections::Generic;

 

    value class Data

    {

    };

 

    int main() {

        List<Object^>^ list = gcnew List<Object^>();

        Data^ data = gcnew Data();

        list->Add(data);

       

        return 0;

    }

   

        值得注意的是,这里的装箱是强类型装箱,即C++/CLI 里常被提及的

   

    "强类型装箱实例"请参见我的另一篇博客 —— .Net 值类型具有引用


     传递
的行为。
 

posted on 2007-12-28 10:51  优哉@游哉  阅读(1197)  评论(1编辑  收藏  举报

导航