gpt4 book ai didi

delphi - 记录中的接口(interface)字段

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

我可以相信记录中的接口(interface)字段总是初始化为nil吗?

TMyRec = record  
FGuard : IInterface;
FObject : TObject;
procedure CheckCreated;
end;

这将允许我写:

procedure TMyCheck.CheckCreated;
begin
if (FGuard = nil) then
begin
FObject := TObject.Create;
FGuard := TGuard.Create (FObject);
end;
end;

(用于自动生命周期管理)

我知道接口(interface)字段被初始化为nil,但是当包含在记录中时也是如此吗?

最佳答案

是的,您可以信赖这一点。

所有引用计数变量:

  • 字符串;
  • 动态数组;
  • 变体;
  • 接口(interface);
  • 包含此类变量的嵌套记录。

初始化为nilrecord已分配,如果您使用 New或动态数组 - 甚至在本地堆栈上。当然,如果你使用普通的GetMem或者使用指针,您必须自己初始化它(例如使用 FillChar )。

如果您好奇,这里有一个对 System.pas 的以下过程的隐藏调用:

procedure _InitializeRecord(p: Pointer; typeInfo: Pointer);

这会将所有引用计数变量内存填充为 0,但不会设置 record 的其他成员。 。事实上,在class例如,整个字段内存初始化为 0,包括所有成员 - 对于 record ,初始化仅适用于引用计数类型。

请注意,在某些情况下,我发现如果您使用 object 则无法正确生成此初始化。输入而不是 record -at least under Delphi 2009-2010 。所以如果你的代码有一些 object类型声明,你最好切换到 record (和松散继承),或显式调用 FillChar .

如果您好奇,这是我用 asm 编写的优化版本 - 可在 our enhanced RTL 中找到。 .

procedure _InitializeRecord(p: Pointer; typeInfo: Pointer);
// this procedure is called at most object creation -> optimization rocks here!
asm
{ -> EAX pointer to record to be initialized }
{ EDX pointer to type info }
MOVZX ECX,[EDX+1] { type name length }
PUSH EBX
PUSH ESI
PUSH EDI
MOV EBX,EAX // PIC safe. See comment above
LEA ESI,[EDX+ECX+2+8] { address of destructable fields }
MOV EDI,[EDX+ECX+2+4] { number of destructable fields }
@@loop:
mov edx,[esi] // type info
mov eax,[esi+4]
mov edx,[edx]
add esi,8
add eax,ebx // data to be initialized
movzx ecx,[edx] // data type
cmp ecx,tkLString
je @@LString
jb @@err
cmp ecx,tkDynArray
je @@DynArray
ja @@err
jmp dword ptr [ecx*4+@@Tab-tkWString*4]
nop; nop; nop // align @@Tab
@@Tab: dd @@WString,@@Variant,@@Array,@@Record
dd @@Interface,@@err
@@LString:
@@WString:
@@Interface:
@@DynArray: // zero 4 bytes in EAX
dec edi
mov dword ptr [eax],0
jg @@loop
POP EDI
POP ESI
POP EBX
RET
@@Variant: // zero 16 bytes in EAX
xor ecx,ecx
dec edi
mov [eax],ecx
mov [eax+4],ecx
mov [eax+8],ecx
mov [eax+12],ecx
jg @@loop
jmp @@exit
@@err:
MOV AL,reInvalidPtr
POP EDI
POP ESI
POP EBX
JMP Error
@@Array:
@@Record: // rarely called in practice
mov ecx,1
call _InitializeArray
dec edi
jg @@loop
@@exit:
POP EDI
POP ESI
POP EBX
end;

关于delphi - 记录中的接口(interface)字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8293664/

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