29

这是一个后续问题:如何隐藏对象的受保护过程?
(我对整个班级助手的概念有点模糊)

假设我有一个像这样的类:

type 
TShy = class(TObject) 
strict private
  procedure TopSecret;
private
  procedure DirtyLaundry;  
protected 
  procedure ResistantToChange;
end; 

我知道如果我有源代码,可以通过在同一单元中添加后代类来访问私有方法。

我有 2 个问题:
- 我如何聘请班级助手来访问strict private会员?
- 我可以在单独的单元中使用类助手来访问(严格)私有成员吗?

4

2 回答 2

38

直到并包括 Delphi 10.0 Seattle,您可以使用类助手来访问strict protectedstrict private成员,如下所示:

unit Shy;

interface

type
  TShy = class(TObject)
  strict private
    procedure TopSecret;
  private
    procedure DirtyLaundry;
  protected
    procedure ResistantToChange;
  end;

unit NotShy;

interface

uses
  Shy;

type
  TNotShy = class helper for TShy
  public
    procedure LetMeIn;
  end;

implementation

procedure TNotShy.LetMeIn;
begin
  Self.TopSecret;
  Self.DirtyLaundry;
  Self.ResistantToChange;
end;

end.

uses
  ..., Shy, NotShy;

procedure TestShy;
var
  Shy: TShy;
begin
  Shy := TShy.Create;
  Shy.LetMeIn;
  Shy.Free;
end;

但是,从 Delphi 10.1 Berlin 开始,这不再有效!类助手不能再访问strict protected,strict privateprivate 成员。这个“功能”实际上是Embarcadero 现在在柏林修复的编译器错误。你运气不好。

于 2012-02-23T09:57:36.223 回答
8

在 Delphi 10.1 Berlin 中删除了对类的访问privatestrict private成员。class helpers请参阅关闭类助手私有访问漏洞

但是仍然存在一个公开的漏洞:

unit Shy;

interface

type
  TShy = class(TObject)
  strict private
    procedure TopSecret;
  private
    procedure DirtyLaundry;
  protected
    procedure ResistantToChange;
  end;

implementation

procedure TShy.DirtyLaundry;
begin
  WriteLn('DirtyLaundry');
end;

procedure TShy.ResistantToChange;
begin
  WriteLn('ResistantToChange');
end;

procedure TShy.TopSecret;
begin
  WriteLn('TopSecret');
end;

end.

Program TestClassHelpers;

{$APPTYPE CONSOLE}

Uses
  Shy;

type
  TNotShy = class helper for TShy
  public
    procedure LetMeIn;
  end;

procedure TNotShy.LetMeIn;
var
  P : procedure of object;
begin
  TMethod(P).Code := @TShy.TopSecret;
  TMethod(P).Data := Self;
  P; // Call TopSecret
  TMethod(P).Code := @TShy.DirtyLaundry;
  TMethod(P).Data := Self;
  P; // Call DirtyLaundry;
  Self.ResistantToChange;  // Protected access works without problems
end;

var
  myObj: TShy;
begin
  myObj := TShy.Create;
  try
    myObj.LetMeIn;
    ReadLn;
  finally
    myObj.Free;
  end;
end.
于 2016-06-11T08:26:37.927 回答