类是我们用来构造 VB.NET 应用程序时的最基本的编程结构了。

那结构与类有什么相似之处与不同之处呢?

结构和类,

相同之处是都含有成员,包括构造函数、方法、属性、字段、常量、枚举和事件,都可以实现接口,都有共享的构造函数,都能对成员进行封装。

没错都有构造函数,那结构的构造函数是什么,结构难道也可被实例化成对象?

看这一段代码:

Module Module1
Private Structure structureA
Dim Name As String
Dim Age As Integer Public Sub New(ByVal _Name As String, ByVal _Age As Integer)
Name = _Name
Age = _Age
End Sub
End Structure Sub Main()
Dim intA As New structureA '无参数的构造函数
Dim intB As New structureA("小明", 17) '有参数的构造函数
End Sub
End Module

怎么样,是不是很好奇,明明只定义一个带参数的构造函数,intB 的实例化我们可以明白,但是是 intA 怎么也能通过编译器检测,给实例化呢?

是不是很好奇,结构怎么也能实例化成对象,和类很象呢!

原因是,每个结构都隐式地具有 Public 无参数实例构造函数也就是 Public Sub New(),该构造函数能产生结构的默认值。所以你平时不写构造函数,也一样可以 New出一个结构来。

事实上,我们在结构类型声明中不能声明无参数的构造函数,只能声明“带参数”的构造函数。都可以用 new 来实例化。

那结构和类在内存分配上难道也是 一样的吗?当然不一样,差别可就大了。

简单来说 ,结构是值类型,而类是引用类型。因此,结构使用堆栈分配,类使用堆(托管堆)分配。

示例:

Module Module1
Private Structure structureA
Dim Name As String
Dim Age As Integer
Public Sub New(ByVal _Name As String, ByVal _Age As Integer)
Name = _Name
Age = _Age
End Sub
End Structure Private Class classA
Public sdNumber As Integer = 0
End Class Sub Main()
Dim stcA As New structureA("小明", 0) '有参数的构造函数
Dim stcB As structureA = stcA
stcB.Age = 17
Dim clsA As New classA
Dim clsB As classA = clsA
clsB.sdNumber = 1001
Console.WriteLine("stcA.Age = {0} ,stcB.Age = {1} ", stcA.Age, stcB.Age)
Console.WriteLine("clsA .sdNumber = {0} ,clsB .sdNumber = {1}", clsA.sdNumber, clsB.sdNumber)
Console.Read()
End Sub
End Module

结果如图:

这就是值类型和引用类型的差别。

结构的实例 stcB.Age 赋值并不影响stcA.Age, 这是因为虽然它们同属于一种SHenry结构,而结构也是属于值类型的,值类型的变量存储在堆栈上的,每个变量都有自己单独的内存空间,所以互不影响。

相反,给 clsB.sdNumber 赋值 17 后; 则会影响slcA.sdNumber 变量的值,这是因为在 Classs 类中,虽然 sdNumber 变量是值类型,但它的对象是类,类是引用类型,而引用类型是存储在堆(托管堆)上,堆上存储的是对象的实际对象值。

不管后面定义多少个 class 类型的变量,只要不实例化,它们都只是在堆栈上划分各自的空间,来存储 class 对象的引用地址,而这每个不同名称的引用地址都指向同一个引用对象的实际值。所以,不管哪个 class 类型变量改变了值,它都会影响原始值。

说得更清楚一点,类作为引用类型,是存储在堆上,只能通过引用地址来访问它们,不能直接访问。

引用类型的变量总是包含该类型的值引用,或包含空引用。空引用不引用任何内容;除分配空引用外,对空引用进行的任何操作都是无效的。

引用类型的变量赋值只会创建引用的一个副本,而不是所引用的值的副本。它们实际上都是会指向同一块存储区的。

结构是直接存储在堆栈上,要么在数组中,要么在另一个类型中 。当包含结构实例的位置被销毁时,结构实例也会被销毁。值类型总是可以直接 访问。我们不能创建对值类型的引用,也不能引用已销毁的值类型实例。值类型的变量总是包含此类型的值。与引用类型不同,值类型的值不能为空引用,也不能引用派生相近程度较大的类型的对象。值类型的变量赋值会创建所赋的值的副 本,当然会新开辟一块内存区来保存值。

那它们还有什么区别没有呢?

当然有很多,比如所有的结构成员都默认为 Public,而类的变量和常量默认为 Private。其他的类成员默认为 Public;结构成员不能声明为 Protected,而类成员可以;结构过程不能处理事件,类过程可以;结构变量声明不能指定初始值、New 关键字或数组初始大小,类变量声明可以。

结构从不终止,所以公共语言运行库从不在任何结构上调用 Finalize 方法;类可由垃圾回收器终止,垃圾回收器会跟踪未完成的引用直到某个特定的实例,当检测到没有剩下的活动引用时, 垃圾回收器将在类上调用 Finalize。”

因为结构是值类型,是由系统统一管理内存,不是引用,所以不会对内存造成危害。

还有结构是不可继承的,而类可以继承。其实结构自身是从 ValueType 类隐式继承下来的。

数据类型可分为值类型和引用类型。值类型要么是堆栈分配的,要么是在结构中以内联方式分配的。引用类型是堆分配的,引用类型和值类型都是从最终的基类 Object 派生出来的。当值类型需要充当对象时 ,就在堆上分配一个包装,该包装能使值类型看上去像引用对象一样,并且将该值类型的值复制给它。该包装被加上标记,以便系统知道它包含一个值类型。这个过程程称为装箱,其反向过程程称为拆箱。装箱和拆箱能够使任何类型像对象一样进行处理。

VB.NET 结构(Structure)和类(Class)的区别的更多相关文章

  1. C++中 结构体和类的异同

    在C++中,结构体是一种特殊形态的类. 结构体和类的唯一区别就是:  结构体和类具有不同的默认访问控制属性. 类中,对于未指定访问控制属性的成员,其访问控制属性为私有类型(private) 结构体中, ...

  2. 介绍C#结构体与类区别

    1. 结构体与类定义方式 结构体定义使用struct类定义使用class 结构体: struct testDemo{ int num; void action(){ } } 类: class test ...

  3. Swift结构体和类

    Swift结构体 在Swift标准中,绝大多数的公开的类型都是结构体,而枚举和类只占很小的一部分 比如Bool.Int.Double.String.Array.Dictionary等常见的类型都是结构 ...

  4. c#中结构体(struct)和类(class)的区别

    一.类与结构的示例比较: 结构示例: public struct Person { string Name; int height; int weight public bool overWeight ...

  5. C#中结构体和类的区别

    结构体和类同样能够定义字段,方法和构造函数,都能实例化对象,这样看来结构体和类的功能好像是一样的了,但是他们在数据的存储上是不一样的 C#结构体和类的区别问题:这两种数据类型的本质区别主要是各自指向的 ...

  6. C#中的结构体与类的区别

    经常听到有朋友在讨论C#中的结构与类有什么区别.正好这几日闲来无事,自己总结一下,希望大家指点. 1. 首先是语法定义上的区别啦,这个就不用多说了.定义类使用关键字class 定义结构使用关键字str ...

  7. 转载 C#结构体(struct)和类(class)的区别

    转载原地址: http://dotnet.9sssd.com/csbase/art/8 C#结构体和类的区别问题:在C#编程语言中,类属于引用类型的数据类型,结构体属于值类型的数据类型,这两种数据类型 ...

  8. Swift结构体与类

    在面向过程的编程语言(如C语言)中,结构体用得比较多,但是面向对象之后,如在C++和Objective-C中,结构体已经很少使用了.这是因为结构体能够做的事情,类完全可以取而代之.而Swift语言却非 ...

  9. C++中结构体与类的区别(结构不能被继承,默认是public,在堆栈中创建,是值类型,而类是引用类型)good

    结构是一种用关键字struct声明的自定义数据类型.与类相似,也可以包含构造函数,常数,字段,方法,属性,索引器,运算符和嵌套类型等,不过,结构是值类型. 1.结构的构造函数和类的构造函数不同. a. ...

  10. C C++ 中结构体与类

    先来说说C和C++中结构体的不同 a) C语言中的结构体不能为空,否则会报错 1>d:\myproject\visual studio 2013\projects\myc++\main.c(71 ...

随机推荐

  1. NSData、NSString 、 NSFileManager

      1 NSData和NSMutableData的基本使用 1.1 问题 NSData类是IOS提供的用于以二进制的形式操作文件数据的类,NSData有两个常用的属性length和bytes,leng ...

  2. POJ 1723 SOLDIERS (中位数)

    题目大意: 平面上有N(N<=10000)个点,求这些点变成一条水平线的最小移动步数. 算法讨论: 表示自己太弱弱了,打算从今天开始提高一下智商. 我们考虑,既然是要成一条水平线,那么这条直线的 ...

  3. (原)Ubuntu16中卸载并重新安装google的Protocol Buffers

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5782992.html 目前最新的是1.6.1 1. 卸载掉老版本的Protocol: sudo apt ...

  4. chisel中pviews命令无法使用

    chisel是用Python写的LLDB调试器插件,用来调试iOS应用非常方便,相关下载安装链接如下:https://github.com/facebook/chisel.本人安装之后,在xcode里 ...

  5. MySql存储引擎介绍

    MySQL5.5以后默认使用InnoDB存储引擎,其中InnoDB和BDB提供事务安全表,其它存储引擎都是非事务安全表.若要修改默认引擎,可以修改配置文件中的default-storage-engin ...

  6. LINUX SSH客户端的中文乱码问题

       原因在于文件/etc/sysconfig/i18n 这个文件是系统的区域语言设置, i18n是 国际化internationalization的缩写 i和n之间正好18个字母 解释: LANG= ...

  7. 开源C/C++网络库比较

    在开源的C/C++网络库中, 常用的就那么几个, 在业界知名度最高的, 应该是ACE了, 不过是个重量级的大家伙, 轻量级的有libevent, libev, 还有 Boost的ASIO. ACE是一 ...

  8. 【Xamarin挖墙脚系列:代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧(转)】

    正愁如何选择构建项目中的视图呢,现在官方推荐画板 Storybord...但是好像 xib貌似更胜一筹.以前的老棒子总喜欢装吊,用代码写....用代码堆一个HTML页面不知道你们尝试过没有.等页面做出 ...

  9. eclipse工具再学习

    今天下午最后近1小时及晚上2个多小时,我都花费时间在工程环境配置上,自尊心被严重摧残,各种郁闷和抱怨.源头是我部分刷新代码后运行工程依赖的jar报错,后来找同事发现是因为我没更新pom.xml文件,重 ...

  10. 剑指offer-面试题2.实例Singleton模式

    题目:设计一个类,我们只能生成该类的一个实例 这道题显然是对设计模式的考察,很明显是单例模式.什么是单例模式呢,就是就像题目所说的只能生成一 个类的实例.那么我们不难考虑到下面几点: 1.不能new多 ...