关于构造函数与析构函数

hiyo 2003-11-13 08:46:22
谁能详细说说二者的用法,另外析构函数是否在程序结束时自动调用。
...全文
222 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
cimoka 2003-11-13
  • 打赏
  • 举报
回复
哈哈,看看微软的msdn吧!


构造函数是允许控制初始化的特殊方法。它们在程序开始之后或在创建类型的实例时运行。与其他成员不同,构造函数不是继承的,而且不向类型的声明空间引入名称。构造函数只能由对象创建表达式或 .NET Framework 调用;它们永远不能被直接调用。

将变量初始值设定项看作是自动插入构造函数块的语句是有用的。下面的示例包含若干变量初始值设定项:

Imports System.Collections
Class A
Private x As Integer = 1
Private y As Integer = - 1
Private count As Integer

Public Sub New()
count = 0
End Sub

Public Sub New(n As Integer)
count = n
End Sub
End Class

Class B
Inherits A
Private sqrt2 As Double = Math.Sqrt(2.0)
Private items As New ArrayList(100)
Private max As Integer

Public Sub New()
Me.New(100)
items.Add("default")
End Sub

Public Sub New(n As Integer)
MyBase.New(n-1)
max = n
End Sub
End Class
此例对应于下面显示的代码,其中的每个注释都指示一个自动插入的语句:

Imports System.Collections
Class A
Private x, y, count As Integer

Public Sub New()
MyBase.New() ' Invoke object() constructor.
x = 1 ' This is a variable initializer.
y = - 1 ' This is a variable initializer.
count = 0
End Sub

Public Sub New(n As Integer)
MyBase.New() ' Invoke Object constructor.
x = 1 ' This is a variable initializer.
y = - 1 ' This is a variable initializer.
count = n
End Sub
End Class

Class B
Inherits A
Private sqrt2 As Double
Private items As ArrayList
Private max As Integer

Public Sub New()
Me.New(100)
items.Add("default")
End Sub

Public Sub New(n As Integer)
MyBase.New(n - 1)
sqrt2 = System.Math.Sqrt(2.0) ' This is a variable initializer.
items = New ArrayList(100) ' This is a variable initializer.
max = n
End Sub
End Class
注意,变量初始值设定项被转换为赋值语句,而这些赋值语句在基类构造函数调用“之后”执行。这种顺序确保了所有基实例变量在可访问实例的“任何”语句执行之前,由它们的变量初始值设定项初始化,如下例所示:

Class A
Dim x As Integer = 1
End Class

Class B
Inherits A
Private y As Integer = x

Public Sub New()
Console.WriteLine("x = " & x & ", y = " & y)
End Sub
End Class
当使用 New B() 创建 B 的实例时,产生如下输出结果:

x = 1, y = 1
y 的值为 1,因为变量初始值设定项在基类构造函数调用之后执行。

ConstructorMemberDeclaration ::= InstanceConstructorDeclaration | SharedConstructorDeclaration(构造函数成员声明 ::= 实例构造函数声明 | 共享构造函数声明)



不能对结构使用析构函数。只能对类使用析构函数。

一个类只能有一个析构函数。

无法继承或重载析构函数。

无法调用析构函数。它们是被自动调用的。

析构函数既没有修饰符,也没有参数。例如,下面是类 MyClass 的析构函数的声明:

~ MyClass()
{
// Cleanup statements.
}
该析构函数隐式地对对象的基类调用 Object.Finalize 方法。这样,前面的析构函数代码被隐式地转换为:

protected override void Finalize()
{
try
{
// Cleanup statements.
}
finally
{
base.Finalize();
}
}
这意味着对继承链中的所有实例递归地(从派生相近程度最大的到派生相近程度最小的)调用 Finalize 方法。

程序员无法控制何时调用析构函数,因为这由垃圾回收器决定的。垃圾回收器检查是否存在应用程序不再使用的对象。它认为这些对象符合销毁条件并回收这些对象占用的内存。程序退出时也会调用析构函数。

可以通过调用 GC.Collect 方法强制进行垃圾回收,但大多数情况下应避免这样做,因为这样会导致出现性能问题。有关更多信息,请参见强制垃圾回收。

示例
下面的示例创建三个类,这三个类构成了一个继承链。类 First 是基类,Second 是从 First 派生的,而 Third 是从 Second 派生的。这三个类都有析构函数。在 Main() 中,创建了派生相近程度最大的类的实例。程序运行时,注意这三个类的析构函数会自动被调用,并且是按照从派生相近程度最大的到派生相近程度最小的次序调用。

// Destructors1.cs
using System;

class First
{
~First()
{
Console.WriteLine("First's destructor is called");
}
}

class Second: First
{
~Second()
{
Console.WriteLine("Second's destructor is called");
}
}

class Third: Second
{
~Third()
{
Console.WriteLine("Third's destructor is called");
}
}

public class MainClass
{
public static void Main()
{
Third myObject = new Third();
}
}
输出
Third's destructor is called
Second's destructor is called
First's destructor is called
使用析构函数释放资源
一般来说,您不必像使用 C++ 时那样关注内存管理。这是因为 .NET Framework 垃圾回收器会隐式地管理对象的内存分配和释放。但是,当应用程序封装窗口、文件和网络连接这类非托管资源时,应当使用析构函数释放这些资源。当对象符合销毁条件时,垃圾回收器会运行对象的 Finalize 方法。

资源的显式释放
如果您的应用程序在使用昂贵的外部资源,则还建议您提供一种在垃圾回收器释放对象前显式地释放资源的方式。可通过实现 Dispose 方法(来自 IDisposable 接口)来完成这一点,该方法为对象执行必要的清理。这样可大大提高应用程序的性能。即使有这种对资源的显式控制,析构函数也是一种保护措施,可用来在对 Dispose 方法的调用失败时清理资源。


哈哈,看看微软的msdn吧!

16,555

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧