德尔福新手问题

时间:2010-09-06 09:26:11

标签: delphi

我有几个新手问题,我似乎找不到答案。

变量

我注意到在某些应用程序中,它们在表单类型的私有或公共部分中声明变量,但是在其他应用程序中,它们在表单的实现部分中声明它们,是否有理由或者只是用户选择?

程序/功能

我再次注意到,在某些应用程序中,过程/函数在表单类型的私有/公共部分中声明,然后在创建时,它们以表单名称EG为前缀

Procedure Tform1.testproc;
Begin
   Blah
End;

在其他应用程序中,它们未在表单类型中声明,并且不以表单名称为前缀,这是否有原因?还有哪种方法最好?

使用其他单位

是否有一些原因导致某些应用程序在表单实现部分之后将通常用户创建的其他单元添加到uses子句中,而其他应用程序将它们添加到表单单元顶部的uses子句中? 对上述问题的任何帮助/答案都会很棒

非常感谢

科林

3 个答案:

答案 0 :(得分:4)

这一切都取决于能见度。

在单元的接口部分中声明的类型,变量,常量,过程和函数(但在类和其他类型定义之外)对其他单元是可见的,而在类型,变量,常量,过程和函数中声明的类型,变量,常量,过程和函数单元的实现部分只能在同一个单元中使用(并且仅在声明之下)。因此,如果您需要特定单元中的类型/变量/函数/ ...但是不希望标识符在单元外部有意义,那么在实现部分中在需要之前声明它们是个好主意

此外,当谈到时,它们的标识符可以声明为私有,严格私有,公共,保护和发布。这也是由于不同类型的可见性。私有标识符只能在类本身内使用(或在同一单元中定义的其他类,除非 strict private),依此类推。

另外,请注意:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
  private
    { Private declarations }
    alpha: integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

var
  beta: integer;

implementation

{$R *.dfm}

end.

由于alpha TForm1的成员,因此该类的每​​个实例,即此表单的每个对象(即,每个创建的表单)这个类)将拥有自己的 alpha变量。另一方面,在任何类之外的单元中声明的beta是“每个单元一个”,也就是说,每个TForm1对象将看到相同的beta。 (然后还有“类变量”等。请参阅文档以获取更多详细信息。)

(另外,你可能已经知道了这一点,但在像

这样的情况下
unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm3 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

procedure TForm3.FormCreate(Sender: TObject);
begin
  beep;
end;

end.

您没有两个名为FormCreate的函数,但只有一个函数。对此函数的第一个引用是声明,它是interface部分中类声明的一部分,这是其他类和单元将看到的。 FormCreate函数(或其定义)的实际实现始终位于implementation部分。实际上,其他类或单元不需要知道特定类中函数的确切实现。)

最后,我想推荐官方的Delphi文档,这非常好。从http://docwiki.embarcadero.com/RADStudio/en/Delphi_Language_Guide_Index开始。

答案 1 :(得分:0)

变量/步骤/功能

这一切都取决于信息的去向。

如果它是特定于表单实例的方法或变量,那么您必须在表单类型本身中声明它。如果它适用于表单的所有实例,那么您将它放在实现部分中,使其成为全局 - 它不属于该类型。

在许多情况下,您一次不会有多个单个表单的实例,因此在这种情况下,就功能而言,通常无论您在何处放置它 - 但是将所谓的可能性放在表单类型中而不是在实现部分中,这被认为是一种很好的做法。这是因为它保留了与表单本身相关的信息,而不是依赖于基本上可以从任何地方访问的全局信息。

用途

有两个不同的地方可以放置uses子句,你已经注意到了它们。

需要这样做的原因是因为Delphi编译器是作为单通道编译器实现的。这使得它很快,但它也意味着你必须提前声明所有内容,因此它知道会发生什么。

implementation关键字后使用uses子句时,在声明所有类型之后才会读取该单元。这允许你有units refer to each other,即Unit1引用Unit2而Unit2引用Unit1,因为在引入对另一个的依赖之前,所有必需的定义都是可用的。如果两者都是从“顶部”使用条款中相互引用,那么这是不可能的。

由于您可以确定VCL单位不会引用代码中的任何单位,因此可以安全地将其包含在顶部。关于您在项目中创建的单元,不一定能说同样的内容,因此将它们添加到另一个uses子句中会更安全。

答案 2 :(得分:0)

这完全是关于Delphi的模块系统(模块在这里被称为单元)。

当您在单元的接口部分内声明某些内容时,所有其他单元都可以看到它。 而实施仅适用于此单元 在处理课程时,私人 / 公开仅与此特定班级的成员有关。

考虑一下:

unit A 
//------------------------------------------------

Interface

uses ... // modules on which *iterface* depends
         // don't include here modules needed for implementation only
//------------------------------------------------

var visibleVar: Integer; // visible from other units
//------------------------------------------------

type VisibleType = class
public: 
    visibleMember: Integer; // visible from other units and classes
private:
    invisibleMember: Integer; // invisible from other units, but
                              // visible to other classes in this unit
strict private:
    reallyInvisible: Integer; // visible *only* inside this class
end;

//------------------------------------------------
//------------------------------------------------
//------------------------------------------------

Implementation

uses ... // modules on which *implementation* depends (and interface is *not*)
//------------------------------------------------

var invisibleVar: Integer; // can't reference to this from other units
//------------------------------------------------

type InvisibleType = class // can be referenced only from inside this module
public: 
    modulePrivateMember: Integer; // visible only inside module's implementation
private:
    invisibleMember: Integer; // in *this context* essentially the same as "public"
strict private:
    reallyInvisible: Integer; // same as in interface - it's just private
end;