gpt4 book ai didi

delphi - 使用虚拟类访问私有(private)字段

转载 作者:行者123 更新时间:2023-12-03 03:22:28 25 4
gpt4 key购买 nike

我有此声明:

Type

TmyObjA = class
private
FieldA: integer;
FieldB: integer;
public
...
end;

TmyObjB = class(TmyObjA)
private
FieldC: integer;
FieldD: integer;
public
...
end;

var MyObjB = TmyObjB

我现在想要访问 MyObjB私有(private)字段 FieldA。我确实喜欢这样:

  TmyObjAPrivateAccess = class
public
FieldA: integer;
FieldB: integer;
end;

TmyObjAPrivateAccess(MyObjB).FieldA := something;

它会起作用还是我必须这样做:

  TmyObjBPrivateAccess = class
public
FieldA: integer;
FieldB: integer;
FieldC: integer;
FieldD: integer;
end;

TmyObjBPrivateAccess(MyObjB).FieldA := something;

注意:我进行了测试,它在两种变体中都有效,但这不是演示,它只是看起来有效

<小时/>

编辑/注释

关于为什么我需要访问私有(private)成员:我要访问私有(private)成员的类是TTexture:

  TTexture = class(TInterfacedPersistent, ITextureAccess)
private
FWidth: Integer;
FHeight: Integer;
FPixelFormat: TPixelFormat;
FHandle: TTextureHandle;
FStyle: TTextureStyles;
FMagFilter: TTextureFilter;
FMinFilter: TTextureFilter;
FTextureScale: Single;
FRequireInitializeAfterLost: Boolean;
FBits: Pointer;
FContextLostId: Integer;
FContextResetId: Integer;
protected
public
property BytesPerPixel: Integer read GetBytesPerPixel;
property MinFilter: TTextureFilter read FMinFilter write SetMinFilter;
property MagFilter: TTextureFilter read FMagFilter write SetMagFilter;
property PixelFormat: TPixelFormat read FPixelFormat write SetPixelFormat;
property TextureScale: Single read FTextureScale; // hi resolution mode
property Style: TTextureStyles read FStyle write SetStyle;
property Width: Integer read FWidth write SetWidth;
property Height: Integer read FHeight write SetHeight;
property Handle: TTextureHandle read FHandle;
end;

这是我的TmyObjA

然后我将此类更新为

TALPlanarTexture = class(TTexture)
private
FSecondTexture: TTexture;
FThirdTexture: TTexture;
FFormat: TALTextureFormat;
protected
....
end;

这是我的TmyObjB。但我还有其他几个类似的类,例如 TALBiPlanarTexture = class(TALTexture) 等。这就是为什么我只想拥有一个访问 所有人的类(class):

  {************************}
{$IF CompilerVersion > 32} // tokyo
{$MESSAGE WARN 'Check if FMX.Types3D.TTexture still has the exact same fields and adjust the IFDEF'}
{$ENDIF}
TALTextureAccessPrivate = class(TInterfacedPersistent)
public
FWidth: Integer;
FHeight: Integer;
FPixelFormat: TPixelFormat;
FHandle: TTextureHandle;
FStyle: TTextureStyles;
FMagFilter: TTextureFilter;
FMinFilter: TTextureFilter;
FTextureScale: Single;
FRequireInitializeAfterLost: Boolean;
FBits: Pointer;
FContextLostId: Integer;
FContextResetId: Integer;
protected
public
end;

现在为什么我需要访问 TTExture 的私有(private)成员? TTexture 是一个非常简单的类,所有 OpenGL delphi 框架都使用它。因此,替换此类意味着......很好的意思是重绘所有 openGL firemonkey 框架:) 相当复杂的工作,但我同意对于不想访问私有(private)成员的纯粹人来说这是一种可能性。

我有另一个框架(视频播放器),它在每个视频帧上给我一个带有高度和比例的 openGL 纹理 ID。因此,在每个新帧事件中,我需要更新我的 TTexture 的句柄以及它的 With/height 并将其发送到 Canvas .drawTexture(仅接受 TTexture)

有没有办法在每个帧上更新具有给定Handle/宽度/高度TTexture对象> 和规模?简单的回答:不!是的,他们是一种方法,但我发现它比直接访问私有(private)成员更危险。这种方式涉及使用ITextureAccess将句柄重置为零,然后调用setwithsetheight,这将最终确定纹理,然后仅在设置回句柄后,等等...

但无论如何,我的问题不是访问私有(private)成员是好是坏:)

最佳答案

如果您控制所有类,那么这是一个糟糕的设计选择。然而,您似乎正在尝试访问一些 VCL 内部结构。如果您确定没有干净的方法来获取所需的信息,那么您所做的就是正确的。

您基本上是在定义一个与原始类具有相同布局的新类,然后,您无需进行类型检查即可进行转换:因为您要访问的字段位于两个类中的偏移量相同,您最终将访问所需的内存。

您的第二个示例之所以有效,是因为用户字段正确对齐。如果您想访问 A 的私有(private)字段,最好使用具有最少填充量的访问器来达到所需的偏移量,这样您需要维护的字段就会更少。您应该记录您想要访问的字段以供将来引用,以及原始类定义,以便您可以发现布局随时间的变化。

请记住,当原始类更改其自己的布局时,这个肮脏的技巧将不再按预期工作。根据类的重构方式,您的代码可能会读取错误的值,或者因访问冲突而崩溃。

更新首先,OP 要求访问普通类中的私有(private)字段。接口(interface)没有处理这个答案,因为它们是按照 @rudy 所描述的方式布局的,并且显然很难访问这些字段。

关于delphi - 使用虚拟类访问私有(private)字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53899711/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com