.Net--必须知道Class和struct的关系[转]

转载 2007年09月18日 13:14:00
1. 引言
  提起class和struct,我们首先的感觉是语法几乎相同,待遇却翻天复地。历史将接力棒由面向过程编程传到面向对象编程,class和struct也背负着各自的命运前行。在我认为,struct英雄迟暮,class天下独行,最本质的区别是class是引用类型,而struct是值类型,它们在内存中的分配情况有所区别。由此产生的一系列差异性,本文将做以全面讨论。

  2. 基本概念
  2.1. 什么是class?
  class(类)是面向对象编程的基本概念,是一种自定义数据结构类型,通常包含字段、属性、方法、属性、构造函数、索引器、操作符等。因为是基本的概念,所以不必在此详细描述,读者可以查询相关概念了解。我们重点强调的是.NET中,所有的类都最终继承自System.Object类,因此是一种引用类型,也就是说,new一个类的实例时,对象保存了该实例实际数据的引用地址,而对象的值保存在托管堆(managed heap)中。

  2.2. 什么是struct?
  struct(结构)是一种值类型,用于将一组相关的信息变量组织为一个单一的变量实体 。所有的结构都继承自System.ValueType类,因此是一种值类型,也就是说,struct实例分配在线程的堆栈(stack)上,它本身存储了值,而不包含指向该值的指针。所以在使用struct时,我们可以将其当作int、char这样的基本类型类对待。  

  3. 相同点,不同点
  相同点:语法类似。
  不同点:
  ·class是引用类型,继承自System.Object类; struct是值类型,继承自System.ValueType类,因此不具多态性。但是注意,System.ValueType是个引用类型。
  ·从职能观点来看,class表现为行为; 而struct常用于存储数据。
  ·class支持继承,可以继承自类和接口; 而struct没有继承性,struct不能从class继承,也不能作为class的基类,但struct支持接口继承(记得吗,《第二回:对抽象编程:接口和抽象类》也做过讨论)
  ·class可以声明无参构造函数,可以声明析构函数; 而struct只能声明带参数构造函数,且不能声明析构函数。因此,struct没有自定义的默认无参构造函数,默认无参构造器只是简单地把所有值初始化为它们的0等价值
  ·实例化时,class要使用new关键字; 而struct可以不使用new关键字,struct在声明时就进行了初始化过程,所有的成员变量均默认为0或null。
  ·class可以实抽象类(abstract),可以声明抽象函数; 而struct为抽象,也不能声明抽象函数。
  ·class可以声明protected成员、virtual成员、sealed成员和override成员; 而struct不可以,但是值得注意的是,struct可以重载System.Object的3个虚方法,Equals()、ToString()和GetHashTable()。

  ·class的对象复制分为浅拷贝和深拷贝(该主题我们在本系列以后的主题中将重点讲述,本文不作详述),必须经过特别的方法来完成复制; 而struct创建的对象复制简单,可以直接以等号连接即可。
  ·class实例由垃圾回收机制来保证内存的回收处理; 而struct变量使用完后立即自动解除内存分配。
  ·作为参数传递时,class变量是以按址方式传递; 而struct变量是以按值方式传递的。

  我们可以简单的理解,class是一个可以动的机器,有行为,有多态,有继承; 而struct就是个零件箱,组合了不同结构的零件。其实,class和struct最本质的区别就在于class是引用类型,内存分配于托管堆; 而struct是值类型,内存分配于线程的堆栈上。由此差异,导致了上述所有的不同点,所以只有深刻的理解内存分配的相关内容,才能更好的驾驭。本系列将再以后的内容中,将引用类型和值类型做以深入的比较和探讨,敬请关注。当然正如本文标题描述的一样,使用class基本可以替代struct的任何场合,class后来居上。虽然在某些方面struct有性能方面的优势,但是在面向对象编程里,基本是class横行的天下。

  那么,有人不免会提出,既然class几乎可以完全替代struct来实现所有的功能,那么struct还有存在的必要吗?答案是,至少在以下情况下,鉴于性能上的考虑,我们应该考虑使用struct来代替class:
  ·实现一个主要用于存储数据的结构时,可以考虑struct。
  ·struct变量占有堆栈的空间,因此只适用于数据量相对小的场合。
  ·结构数组具有更高的效率。
  ·提供某些和非托管代码通信的兼容性。
  所有这些是struct有一席之地的理由,当然也许还有其他的更多说法,只是我不知道罢了:-) 

相关文章推荐

[你必须知道的.NET] 第四回:后来居上:class和struct

本文将介绍以下内容: • 面向对象基本概念 • 类和结构体简介 • 引用类型和值类型区别 1. 引言 提起class和struct,我们首先的感觉是语法几乎相同,待遇却翻天复地。历史将接力棒...

.NET中struct与class的区别

在.net中的struct与class有很多相似之处,比如可以直接new,对于成员可以直接XX.field,以至于有不少程序员在用时,将其混在一起,分不清有何区别。这两者有何区别呢? 1.类型不同 ...

ASP.NET MVC中你必须知道的13个扩展点[转]

ScottGu在其最新的博文中推荐了Simone Chiaretta的文章13 ASP.NET MVC extensibility points you have to know,该文章为我们...

C++中 struct和class的关系

从语法上,在C++中(只讨论C++中)。class和struct做类型定义时只有两点区别:   (一)默认继承权限。如果不明确指定,来自class的继承按照private继承处理,来自struc...

[你必须知道的.NET]第十回:品味类型---值类型与引用类型(下)-应用征途

转自:http://www.cnblogs.com/anytao/archive/2007/06/18/must_net_10.html 本文将介绍以下内容: 类型的基本概念  值类型深入 引用...

必须知道的.NET

好书不能只读一遍,这两天又翻看了一遍《你必须知道的.NET》,重温了下基础,重温了下经典,简单记录了下来。 内存分配:CLR 管理内存的区域,主要有三块,分别为:线程的堆栈,用于分配值类型实例。堆栈主...

[你必须知道的.NET] 第二回:对抽象编程:接口和抽象类

转自:http://www.cnblogs.com/anytao/archive/2007/04/12/must_net_02.html 本文将介绍以下内容: • 面向对象思想:多态 • 接口...

你必须知道的.NET——内存分配

在分析内存分配时,应该先了解关于堆栈的区别 堆的分配向高地址扩展,而栈的分配向低地址扩展。 二。内存分配 关于内存的分配,首先应该了解分配在哪里的问题。CLR管理内存的区域,主要有三...

你必须知道的.NET之特性和属性

1. 引言 attribute是.NET框架引入的有一技术亮点,因此我们有必要花点时间走进一个发现attribute登堂入室的入口。因为.NET Framework中使用了大量的定制特性来完成代码约...

[你必须知道的.NET] 第六回:深入浅出关键字---base和this

转自:http://www.cnblogs.com/anytao/archive/2007/05/04/must_net_06.html 本文将介绍以下内容: 面向对象基本概念 base关键字...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)