类模块和标准模块的比较 
类模块和标准模块的不同点在于存储数据方法的不同。标准模块的数据只有一个备份。这意味着标准模块中一个公共变量的值改变以后,在后面的程序中再读取该变量时,它将得到同一个值。而类模块的数据,是相对于类实例(也就是,由类创建的每一对象)而独立存在的。同样的,标准模块中的数据在程序作用域内存在,也就是说,它存在于程序的存活期中;而类实例中的数据只存在于对象的存活期,它随对象的创建而创建,随对象的撤消而消失。最后,当变量在标准模块中声明为 Public 时,则它在工程中任何地方都是可见的;而类模块中的 Public 变量,只有当对象变量含有对某一类实例的引用时才能访问。上面的比较,同样适用于标准模块和类模块中的公共过程。用下面的例子可以说明。打开一个新 Standard Exe 工程,并在“工程”菜单中个添加一个标准模块和一个类模块,然后运行以下的代码:把下面的代码放在 Class1 中;'下面是 Class1 对象的一个属性。
Public Comment As String'下面是 Class1 对象的一个方法。
Public Sub ShowComment()
   MsgBox Comment, , gstrVisibleEverywhere
End Sub把下面的代码放在 Module1 中:'标准模块中的代码是全局的。
Public gstrVisibleEverywhere As StringPublic Sub CallableAnywhere(ByVal c1 As Class1)
   '下行改变一个全局变量,这是一个 Class1 实例的(属性)。
      '只有传递给该过程的个别对象才受到影响。
      c1.Comment = "Touched by a global function."
End Sub把两个命令按钮放在 Form1 上,并在 Form1 中添加以下的代码:Private mc1First As Class1
Private mc1Second As Class1Private Sub Form_Load()
   '创建两个 Class1 类的实例。
   Set mc1First = New Class1
   Set mc1Second = New Class1
   gstrVisibleEverywhere = "Global string data"
End SubPrivate Sub Command1_Click()
   Call CallableAnywhere(mc1First)
   mc1First.ShowComment
End SubPrivate Sub Command2_Click()
   mc1Second.ShowComment
End Sub按 F5 键,运行该工程。当 Form1 加载时,它创建两个 Class1 类实例,每个实例有自己的数据。同时,Form1 设置了下面全局变量 gstrVisibleEverywhere 的值。按下 Command1,调用全局过程并传递引用给第一个 Class1 对象。全局过程设置 Comment 属性,然后 Command1 调用 ShowComment 方法显示该对象的数据。正如图 9.6 所示,结果信息框演示了全局过程 CallableAnywhere 如何设置对象的 Comment 属性,而且全局字符串在 Class1 内部是可见的。图 9.6 第一个 Class1 对象的信息框按下 Command2,调用第二个 Class1 类实例的 ShowComment 方法。如图 9.7 所示,两个对象都访问了全局字符串变量;然而,第二个对象的 Comment 属性是空的,因为对全局过程 CallableAnywhere 的调用只改变第一个对象的 Comment 属性。图 9.7 第二个 Class1 对象的信息框重点 要避免类的代码依赖于全局变量,也就是标准模块中的公共变量。一个类的许多实例可以同时存在,所有这些对象在程序中共享全局数据。在类模块代码中使用全局变量也违背了面向对象封装的编程原则,因为由这样的类所创建的对象并没有包含它们的所有数据。静态类数据
有时,希望由一个类模块所创建的一些对象共享某个数据项。这就是所谓的静态类数据。不能在 Visual Basic 类模块中实现真正的静态类数据。但是,通过使用 Property 过程在标准模块中设置及返回 Public 数据成员的值,可以仿真静态类数据。如以下的代码:'只读属性返回应用程序的名字。
Property Get CommonString() As String
   '变量 gstrVisibleEverywhere 保存在
   '标准模块中,并声明为 Public。
   CommonString = gstrVisibleEverywhere
End Property注意   在类模块中,对模块级的变量不能声明为 Static。Static 数据只能在过程中使用。由 Property Let 过程(对于含有对象引用的属性,使用 Property Set)对标准模块数据成员赋予新的值,可以仿真非只读的静态类数据。然而,这种使用全局变量的方式违背了封装编程的原则,而且不推荐使用。例如,变量 gstrVisibleEverywhere 可以在工程中任何地方赋值,甚至可以从别的类代码中赋值,只要该类具有 CommonString 属性。这样做能导致程序中非常微妙的错误。详细信息   ActiveX 部件中的全局数据,与普通程序中的处理方式不同。 如果有 VBP 或 VBE,请参阅《部件工具指南》中的“创建 ActiveX 部件”,“部件设计的一般准则”中的“标准模块与类模块”。

解决方案 »

  1.   

    代码模块
    Visual Basic 的代码存储在模块中。模块有三种类型:窗体、标准和类。简单的应用程序可以只有一个窗体,应用程序的所有代码都驻留在窗体模块中。而当应用程序庞大复杂时,就要另加窗体。最终可能会发现在几个窗体中都有要执行的公共代码。因为不希望在两个窗体中重复代码,所以要创建一个独立模块,它包含实现公共代码的过程。独立模块应为标准模块。此后可以建立一个包含共享过程的模块库。每个标准模块、类模块和窗体模块都可包含: 声明。可将常数、类型、变量和动态链接库 (DLL) 过程的声明放在窗体、类或标准模块的模块级。
    过程。Sub、Function 或者 Property 过程包含可以作为单元来执行的代码片段。本章后面的“过程概述”一节中将讨论这些内容。 
    窗体模块
    窗体模块(文件扩展名为 .FRM )是大多数 Visual Basic 应用程序的基础。窗体模块可以包含处理事件的过程、通用过程以及变量、常数、类型和外部过程的窗体级声明。如果要在文本编辑器中观察窗体模块,则还会看到窗体及其控件的描述,包括它们的属性设置值。写入窗体模块的代码是该窗体所属的具体应用程序专用的;它也可以引用该应用程序内的其它窗体或对象。标准模块
    标准模块(文件扩展名为 .BAS)是应用程序内其它模块访问的过程和声明的容器。它们可以包含变量、常数、类型、外部过程和全局过程的全局(在整个应用程序范围内有效的)声明或模块级声明。写入标准模块的代码不必绑在特定的应用程序上;如果不小心用名称引用窗体和控件,则在许多不同的应用程序中可以重用标准模块。类模块
    在 Visual Basic 中类模块(文件扩展名为 .CLS)是面向对象编程的基础。可在类模块中编写代码建立新对象。这些新对象可以包含自定义的属性和方法。实际上,窗体正是这样一种类模块,在其上可安放控件、可显示窗体窗口。详细信息 关于在类模块中编写代码的更详细的信息,请参阅“用对象编程”。注意 Visual Basic 的专业版和企业版也包含 ActiveX 文档、ActiveX 设计器和用户控件。它们介绍了具有不同文件扩展名的新模块类型。从编写代码的角度来看,这些模块应视同为窗体模块。