【问题标题】:Delphi newbie Questions德尔福新手问题
【发布时间】:2010-09-06 09:26:10
【问题描述】:

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

变量

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

程序/功能

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

Procedure Tform1.testproc;
Begin
   Blah
End;

而在其他应用程序中,它们没有在表单类型中声明,也没有以表单名称为前缀,这是有原因的吗?还有哪个是最好的方法?

使用其他单位

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

非常感谢

科林

【问题讨论】:

    标签: delphi


    【解决方案1】:

    这一切都取决于可见性。

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

    此外,对于,它们的标识符可以声明为私有、严格私有、公共、受保护和发布。这又是由于不同种类的能见度。私有标识符只能在类本身内部使用(或在同一单元中定义的其他类,除非 strict 私有),依此类推。

    另外,请注意:

    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开始。

    【讨论】:

    • “严格私有” - 你的意思可能是“严格私有”
    【解决方案2】:

    变量/过程/函数

    这一切都归结为信息应该去哪里。

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

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

    用途

    uses 子句有两个不同的地方,你已经注意到了。

    之所以需要这样做是因为 Delphi 编译器是作为单遍编译器实现的。这让它很快,但也意味着你必须提前声明一切,所以它知道会发生什么。

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

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

    【讨论】:

      【解决方案3】:

      这都是关于 Delphi 的模块系统(模块在这里称为 units)。

      当您在单元的Interface 部分内声明某些内容时,所有其他单元都可以看到它。 而实施对于本单元可见。
      在处理类时,private / public 仅与该特定类的成员相关。

      考虑:

      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;
      

      【讨论】:

      • 一个小提示:私有成员并不像“严格私有”成员那样私有......
      • @Andreas:感谢您的评论。没有任何访问说明符我得到的是“严格私有”吗?你的回答不清楚
      • 不,您只能获得“私人”。当您说“// 对其他单元和类不可见”时,您的真正意思是“// 对其他单元不可见”——同一单元中的其他类将看到这些标识符。
      猜你喜欢
      • 2018-03-05
      • 2020-04-24
      • 2012-04-19
      • 1970-01-01
      • 2014-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多