Delphi应用程序组织结构

Delphi 中,一个正在开发的应用程序可以被称作项目或者工程。一般地,一个项目主要由 dpr (项目)、 pas (单元)和 dfm (窗体)三种文件组成,另外还有一些附属文件,如 res (资源)文件等。其中项目文件可以被看做是一种特殊的单元。在源代码中,项目文件用关键字 program 标识,单元文件用 unit 标识。

通常,一个项目只有惟一的 dpr 文件。一个 dfm 文件总是有对应的 pas 文件,但是 pas 文件可以没有对应的 pas 文件。

如果打开 Delphi ,选择菜单 File|New|Application ,则可以新建一个项目。该项目包括一个项目文件 Project1.dpr 、一个窗体文件 Unit1.dfm 和一个对应的单元文件 Unit1.pas 。选择菜单 Project|View Source 可以看到项目文件的内容;在窗体上单击右键,从弹出的菜单中选择 View as Text 可以看到窗体文件的内容。

这些文件的内容都必须按照一定的组织结构来编写,编译器按照既定的组织结构来识别这些内容并进行编译。在本节里,我们讨论 program unit 两种单元文件的组织结构。

Program 的组织结构

    一个项目文件被关键字 program 标识,因此,在这里我将项目文件的源代码称作 program 。以下是一个简单的 program

program Project1;   { 文件定义 一个名为 Project1 的项目文件 }

 

uses                 { program 中需要使用到哪些单元 }

  Forms,

  Unit1 in 'Unit1.pas' {Form1} ,

  Dialogs;

 

{ 在这里可以定义一些变量和常量 }

var

  AppMsg: String ;

 

{$R *.res}   {$R 是一个编译指令 此处表示要编译资源文件 Project1.res}

 

{ 这个部分可以实现一个函数和过程 }

procedure AppStart(AppMsg: String );

begin

  ShowMessage(AppMsg);

end ;

 

{begin…end 部分是 program 的主体 这里面的代码是可以运行的 }

begin

  { 应用程序初始化 }

  Application.Initialize;

  Application.Title := 'lxpbuaa';

  { 创建主窗体 }

  Application.CreateForm(TForm1, Form1);

  AppMsg := ' 应用程序马上开始运行。 ';

  AppStart(AppMsg);

  { 应用程序开始运行 }

  Application.Run;

end .

Unit 的组织结构

    一个单元文件被关键字 unit 标识,因此,在这里我将单元文件的源代码称作 unit 。以下是一个完整的 unit

unit Unit1; { 文件定义 一个名为 Unit1 的单元文件 }

 

interface    { 在这个部分声明可供其他单元使用的变量、常量、类型、函数和过程 }

 

uses         {interface 部分的 uses 内容对整个单元都有效 }

  Windows, Messages, Classes, Controls, Forms, Dialogs, Contnrs;

 

type         { 声明类型 }

  TForm1 = class (TForm)

  private

    procedure ShowInfo(Info: String );

  public

    { Public declarations }

  end ;

 

  { 声明函数和过程 }

  procedure ShowInfo(Info: String );

 

var              { 声明变量 }

  Form1: TForm1;

 

implementation   { 在这个部分完成单元的私有声明 并实现 interface 声明的类、函数和
                         
过程 }

 

uses             {implementation 部分的 uses 内容只对 implementation 有效。
                          interface
不需要而 implementation 需要的单元应该在这里引用 }

  SysUtils, Variants;

 

var              {implementation 部分可以和 interface 部分一样进行声明 }

  ObjList: TObjectList;

 

{$R *.dfm}       { 编译对应的 dfm 文件 }

 

{ 实现 interface 部分声明的函数和过程 }

procedure ShowInfo(Info: String );

begin

  ShowMessage(Info);

end ;

 

{ 实现 interface 部分声明的类 }

{ TForm1 }

 

procedure TForm1.ShowInfo(Info: String );

begin

  ShowMessage(Info);

end ;

 

{ 单元初始化部分 }

initialization

  ObjList := TObjectList.Create;

 

{ 单元终止部分 }

finalization

  FreeAndNil(ObjList);

 

end .

从上面的 Unit1 单元可以看到,一个 unit 可以包含五个部分:

1 unit 关键字部分,指定单元的名字。

2 interface 部分。从关键字 interface implementation 为止的内容,都是属于这个部分。该部分可以声明变量、常量、类型、函数和过程,而且它们对于其他单元都是可见的。

3 implementation 部分。在这个部分也可以完成 interface 具有的声明功能,但是它们对于其他单元是不可见的,属本单元私有;同时完成类、函数和过程的实现。

以上三个部分是一个 unit 必须的。接下来的两个部分是可选的。

4 initialization 。在这个部分可以完成单元的初始化工作。如果将一个单元比作一个类,我们知道类的初始化是在构造函数 Create 中完成的,所以 initialization 部分就相当于单元的构造函数。

5 finalization 。在这个部分可以完成单元的终止,完成类似于类的析构函数 Destroy 的功能。

需要注意的是:如果几个单元都有 initialization/finalization 部分,则它们的执行顺序与这些单元在 program uses 字句中的出现顺序一致。所以应该避免 initialization/finalization 部分的代码执行时依赖于它们的执行顺序。


单元循环引用

单元不能被循环引用 Circular unit reference 的。循环引用的意思是 A 引用了 B B 又引用 A 且都是在 interface 部分进行引用。如下面的单元通不过编译:

 

unit Unit1;

 

interface

 

uses

  Unit2;

……

 

unit Unit2;

 

interface

 

uses

  Unit1;

……

  但是如果引用不全发生在 interface 部分,即至少有一个在 implementation 部分,则是允许的。因此,当你需要两个单元相互引用时,应该将其中的一个引用放置在 implementation 部分,否则不能通过编译。

为了避免将来可能的循环引用,对于只在实现部分使用的单元,通常我们都将它写在 implementation 而不是 interface 部分。例如我们编写一个取得一个整型动态数组中最大的元素,需要用到 Math 单元的 Max 函数,此时代码书写应该按照如下所示:

 

unit Unit2;

 

interface

 

{ 因为在声明部分只有一个函数 GetMax 只须引用 System 单元 而该单元是自动引用的 所以
        
在源代码中 接口部分没有任何引用单元的代码行 }

 

  function GetMax(IntDynArray: Array of Integer): Integer;

 

implementation

 

uses Math;      { 在这里而不是接口部分引用单元 Math}

 

function GetMax(IntDynArray: Array of Integer): Integer;

var

  L,I: Integer;

begin

  Result := 0;

  L := Length(IntDynArray);

  if L = 0 then Exit

  else

  begin

    Result := IntDynArray[Low(IntDynArray)];

    for I := Low(IntDynArray)+1 to High(IntDynArray) do

      Result := Max(Result, IntDynArray[I]);

  end ;

end ;

 

end .

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值