Delphi 相互依赖的程序变量和记录
我有以下结构:Delphi 相互依赖的程序变量和记录,delphi,delphi-xe2,forward-declaration,Delphi,Delphi Xe2,Forward Declaration,我有以下结构: program Project26; {$APPTYPE CONSOLE} {$R *.res} type TPrint_address_func = function(offset: integer; info: disassembler_info): boolean; disassembler_info = record data: string; print_address_func: TPrint_address_func; end;
program Project26;
{$APPTYPE CONSOLE}
{$R *.res}
type
TPrint_address_func = function(offset: integer; info: disassembler_info): boolean;
disassembler_info = record
data: string;
print_address_func: TPrint_address_func;
end;
begin
end.
显然,函数类型的记录需要在转发声明中声明。,但是 是否有方法将过程变量声明为前进?
或者我可以用旧的学校对象替换记录并声明为转发吗?您不能转发声明过程类型或记录。因此,结论是必须将类型定义放入记录中:
type
disassembler_info = record
type
TPrint_address_func = function(info: disassembler_info): boolean;
var
data: string;
print_address_func: TPrint_address_func;
end;
type
PDisassembler_info = ^TDisassembler_info;
TPrint_address_func = function(offset: Integer;
info: PDisassembler_info): Boolean;
TDisassembler_info = record
data: string;
print_address_func: TPrint_address_func;
end;
FWIW,一旦我开始在记录中定义类型,我倾向于用可见性说明符来打破声明。我会这样声明这个类型:
type
disassembler_info = record
public
type
TPrint_address_func = function(info: disassembler_info): boolean;
public
data: string;
print_address_func: TPrint_address_func;
end;
info.print_address_func(offset, info);
使用记录助手可以解决此问题
Type
disassembler_info = record
private
FP: Pointer;
public
data: string;
end;
TPrint_address_func = function(info: disassembler_info): boolean;
disassembler_info_helper = record helper for disassembler_info
private
procedure SetAFunc(aF: TPrint_Address_Func);
function GetAFunc: TPrint_Address_Func;
public
property print_address_func: TPrint_address_func read GetAFunc write SetAFunc;
end;
function disassembler_info_helper.GetAFunc: TPrint_Address_Func;
begin
Result := TPrint_address_func(FP);
end;
procedure disassembler_info_helper.SetAFunc(aF: TPrint_Address_Func);
begin
TPrint_address_func(FP) := TPrint_address_func(aF);
end;
助手使用读写方法注入
TPrint\u address\u func
属性,该方法对反汇编程序\u info
中声明的私有变量进行操作。如果传递记录指针,则此问题很容易解决,即使在不支持嵌套记录类型的Delphi版本中也是如此。向前声明记录指针类型,然后使用记录指针声明函数类型。最后,声明记录:
type
disassembler_info = record
type
TPrint_address_func = function(info: disassembler_info): boolean;
var
data: string;
print_address_func: TPrint_address_func;
end;
type
PDisassembler_info = ^TDisassembler_info;
TPrint_address_func = function(offset: Integer;
info: PDisassembler_info): Boolean;
TDisassembler_info = record
data: string;
print_address_func: TPrint_address_func;
end;
您可能会有不止一个函数指针,而且您的记录也可能会有不止一个实例。当您扩展这个模式时,您最终将要重新发明类。考虑这一点:
type
TDisassembler_info = class
data: string;
function print_address(offset: Integer): Boolean; virtual; abstract;
end;
现在,不再定义自由函数,而是声明类的后代并重写抽象方法。随着函数指针和记录实例数量的增加,这有几个优点:
print\u address\u func
,则不会出现空函数指针。如果试图在不重写抽象方法的情况下实例化类,编译器将发出警告type
disassembler_info = record
public
type
TPrint_address_func = function(info: disassembler_info): boolean;
public
data: string;
print_address_func: TPrint_address_func;
end;
info.print_address_func(offset, info);
如果传递的记录参数与调用其函数的记录不同,则肯定是错误的。对于对象,冗余和出错的机会消失了:
info.print_address(offset);
好的,这意味着类型定义仍将在记录外可见,对吗?@Johan是的,它是可见的,但它的名称是
反汇编程序\u info.TPrint\u address\u func
。这是你能做的最好的了。刚刚通过测试发现了这一点。额外的冗长令人失望,但多少可以理解。我想向前声明对象
是不可能的。@Johan你可以检查一下,但我预测答案是否定的。对象是一种值类型,由于Delphi编译器的体系结构,您只能向前声明引用类型。您不能声明一个类型别名,TPrint\u address\u func\u alias=discormer\u info.TPrint\u address\u func代码>?嗯,我很佩服他的足智多谋谢谢罗布,但我特别不想上课。不过,你提出了一个正确的观点。至于指针,它太乱了代码库。