浅析class与struct区别

来源:互联网 发布:java多线程的应用场景 编辑:程序博客网 时间:2024/05/17 00:18

记得以前学C语言老师就讲过struct,那个时候struct主要是用在链表的处理中。后来自己学了C++,才开始接触class,class就不用我介绍了吧。.NET里对structclass这两个关键字都有支持,刚开始学C#的时候就以为C#保留struct是为了与以前的语言兼容一下,struct只是class的另一种表现形式罢了。在看了《Applied Microsoft .Net Framework Programming》后,才发现structclass间的关系并不只是那么简单。

class引用类型,特点:1、内存必须从托管堆分配;2、每个在托管堆中分配的对象有一些与之关联的附加成员必须初始化;3、从托管堆中分配的对象可能会导致垃圾收集。我对引用类型的理解就是个指针。

Struct值类型,分配在线程的堆栈上,不包含指向实例的指针。就像intdoublechar这些值类型一样,也就是他们本身存储了值。 

举个非常简单的例子就能说明问题(这个例子来自那本书):

 1using System;
 2
 3namespace struct与class
 4{
 5    //引用类型
 6    class SomeRef {public int x;}
 7    //值类型
 8    struct SomeVal {public int x;}
 9
10    class Class1
11    {
12        [STAThread]
13        static void Main(string[] args)
14        {
15            SomeRef r1=new SomeRef();
16            SomeVal v1=new SomeVal();
17            r1.x=5;
18            v1.x=5;
19            Console.WriteLine("Before Evaluation:");
20            Console.WriteLine("r1.x="+r1.x);
21            Console.WriteLine("v1.x="+v1.x);
22
23            SomeRef r2=r1;
24            SomeVal v2=v1;
25            r1.x=8;
26            v2.x=9;
27
28            Console.WriteLine("After Evaluation:");
29            Console.WriteLine("r1.x="+r1.x+";r2.x="+r2.x);
30            Console.WriteLine("v1.x="+v1.x+";v2.x="+v2.x);
31        }
32    }
33}
34

结果:

Before Evaluation:

r1.x=5

v1.x=5

 

After Evaluation:

r1.x=8;r2.x=8

v1.x=5;v2.x=9

 

很明显,对v2的修改未影响到v1,对r1的修改影响到了r2

画个图说明一下它们的内存分配:

 

 

那保留struct还有什么用呢,既然都用class。说句老实话,我也觉得没什么用,虽然书上说在线程栈上更快,但毕竟没有GC照顾你,object的深拷贝也比较好实现。权当是C#的一个知识点,记住就行了。

 总结一下区别:

1.   struct在栈里面,class在堆里面。  
   
  2.   struct不支持继承。  
   
  3.   struct   不能有参数为空的构造函数,如果提供了构造函数,必须把所有的变量全都初始化一遍  
   
  4.   不能直接初始化变量。  
   
  5.   struct是值类型,class是引用类型,这是最本质区别。  
   
  6.   struct轻量级,class重量级。  
   
  7.   当涉及数组操作时,struct效率高,涉及collection操作时,class效率高  
        structs   are   somewhat   more   efficient   in   their   use   of   memory   in   arrays   .   however,   they   can   be   less   efficient   when   used   in   collections.   collections   expect   references,   and   structs   must   be   boxed.   there   is   overhead   in   boxing   and   unboxing,   and   classes   might   be   more   efficient   in   large   collections.