在finalization中使用私有方法/ var

Kub*_*taS 2 delphi static properties finalize delphi-xe6

我有(静态)类GT_MyClass

GT_MyClass = class
private
  class var FImage : TJpegImage;

  class function GetImage: TJpegImage;
public
  property Image : TJpegImage  read GetImage;
end;
Run Code Online (Sandbox Code Playgroud)

在函数GetImage我创建FImage如果它还不存在.

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

在最后我想要FreeAndNil(FImage)

finalization
  if Assigned(FImage) then
    FreeAndNil(FImage);
Run Code Online (Sandbox Code Playgroud)

但在最终版块中,我无法看到私有的var FImage ......

你能帮帮我吗?

谢谢!

BTW:我想要属性Image绝对是静态的

Dav*_*nan 5

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

finalization
  if Assigned(GT_MyClass.FImage) then
    FreeAndNil(GT_MyClass.FImage);
Run Code Online (Sandbox Code Playgroud)

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

finalization
  FreeAndNil(GT_MyClass.FImage);
Run Code Online (Sandbox Code Playgroud)

或者你可以提供该类的另一种方法,它更好地封装了这个:

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;
Run Code Online (Sandbox Code Playgroud)

但这仍然让你从课外调用私有方法,这是不理想的.所以你可以使用类析构函数,它是从单元的终结代码中执行的:

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;
Run Code Online (Sandbox Code Playgroud)

不需要最终化代码,编译器会自动确保调用类析构函数.

  • 为什么,为什么地球上的'FreeAndNil`?这是整个计划的终结.什么都不会(或可以)再访问它.这太令人失望了. (3认同)
  • @rudy我跟着提问者的领导.也许你打算向他们提出这个问题?我也不想开始旧的宗教战争.另一个单位可以使用这个,因此可以访问此变量.显然这将是一个错误,但最终确定顺序有时令程序员,甚至经验丰富的程序员感到惊讶 (3认同)