【问题标题】:Use private method/var in finalization在终结中使用私有方法/var
【发布时间】:2016-01-22 20:56:33
【问题描述】:

我有(静态)类 GT_MyClass

GT_MyClass = class
private
  class var FImage : TJpegImage;

  class function GetImage: TJpegImage;
public
  property Image : TJpegImage  read GetImage;
end;

在 GetImage 函数中,如果 FImage 尚不存在,我将创建它。

class function GT_Myclass.GetImage: TJpegImage;
begin
    if not Assigned(FImage) then
    begin
      FImage := TJpegImage.Create;
    end;
    Result := FImage;
end;

最后我想 FreeAndNil(FImage)

finalization
  if Assigned(FImage) then
    FreeAndNil(FImage);

但在完成块中我看不到 private var FImage...

你能帮帮我吗?

谢谢!

顺便说一句:我想让 Image 绝对是静态的

【问题讨论】:

    标签: delphi properties static delphi-xe6 finalize


    【解决方案1】:

    这是由于范围不同。在类方法中,GT_MyClass.GetImage 您的代码在类的范围内,因此可以看到类成员。终结部分在全局范围内执行。所以你可以通过限定名称来编译你的代码:

    finalization
      if Assigned(GT_MyClass.FImage) then
        FreeAndNil(GT_MyClass.FImage);
    

    事实上,测试分配GT_MyClass.FImage 是没有意义的,因为Free 已经这样做了。所以你会写:

    finalization
      FreeAndNil(GT_MyClass.FImage);
    

    或者你可以提供另一个类的方法来更好地封装它:

    type
      GT_MyClass = class
      private
        class var FImage : TJpegImage;
        class function GetImage: TJpegImage;
        class procedure Finalize;
      public
        property Image : TJpegImage  read GetImage;
      end;
    ....
    class procedure GT_MyClass.Finalize;
    begin
      FreeAndNil(FImage); // in scope of class, no need to qualify
    end;
    ....
    finalization
      GT_MyClass.Finalize;
    

    但这仍然会让您从类外部调用私有方法,这并不理想。所以你可以使用class destructor,它是从单元的最终代码中执行的:

    type
      GT_MyClass = class
      private
        class var FImage : TJpegImage;
        class function GetImage: TJpegImage;
        class destructor ClassDestroy;
      public
        property Image : TJpegImage  read GetImage;
      end;
    ....
    class destructor GT_MyClass.ClassDestroy;
    begin
      FreeAndNil(FImage); // in scope of class, no need to qualify
    end;
    

    不需要终结代码,编译器会自动确保调用了类析构函数。

    【讨论】:

    • 非常感谢!漂亮的解决方案(类析构函数)。
    • 为什么,哦,到底为什么FreeAndNil?这是整个程序生命的终结。没有什么会(或可以)再访问它了。这太令人失望了。
    • @rudy 我跟随提问者的领导。也许你是想向他们提出这个问题?我也不想发动旧的宗教战争。另一个单元可以使用这个,因此可以访问这个变量。显然这是一个错误,但最终确定顺序有时会让程序员感到惊讶,即使是有经验的人
    • 如果值可以从类外部访问,FreeAndNil 是正确的选择。仅使用Free 将导致悬空指针。如果之后无法访问,那么您对两者都很好......但是如果,那么您将拥有FreeAndNil 的更好生活。 class destructor 不会在应用程序生命周期的最后被调用...还有更多 class destructorsfinalization 部分等。
    • AFAICT,另一个单元无法访问终结部分中的变量。但是,好吧,我会放弃它。不,Rufo 爵士,这不是最终确定部分的正确选择。单元已经结束,没有任何东西可以访问它的变量了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多