关于构造函数的笔记
pascal吧
全部回复
仅看楼主
level 1
object 类型的构造函数大概是这样
2017年04月01日 01点04分 1
level 1
假设类名为 TFoo (type TFoo = object ...),指向其的指针类型为 PFoo ,
构造函数的参数是 declared parameters ,函数体为 declared body
则它会被转译成这种形式(伪代码)
function Create(this : PFoo;
vmt : Pointer;
{ declared parameters }
) : PFoo;
// local variables
begin
this:=PFoo(fpc_help_constructor(this, vmt, OFFSETOF(TFoo, __VPTR)));
if this=nil then
exit(this);
try
{ declared body }
except
fpc_help_fail(this, vmt, OFFSETOF(TFoo, __VPTR));
raise;
end;
exit(this);
end;
其中 vmt 是虚表地址,若无虚表则为 nil 。
OFFSETOF(TFoo, __VPTR) 为虚表指针在对象中的偏移,若无虚表则为 0 。
fpc_help_constructor 为编译器提供的函数,功能有二
1) 若传入的 this 是 nil ,则在堆上分配空间(使用 GetMem),并做一下记录
2) 若传入的 this 不是 nil 或分配完成后,将对象全部字节设为 $00 ,然后若有虚表则再设置虚表;
fpc_help_fail 为编译器提供的过程。功能是若构造过程中抛出异常,且之前记录了对象分配在堆上,则将对象释放。
x.Create(params) 被转译成 Create(@x, VMTOF(TFoo), OFFSETOF(TFoo, __VPTR), params)
new(ptr, Create(params)) 被转译成 ptr:=Create(nil, VMTOF(TFoo), OFFSETOF(TFoo, __VPTR), params)
2017年04月01日 02点04分 2
level 1
关于虚函数
(Debug 模式下)调用虚函数前 FPC 会检查 class 或指向 object 的指针是否为 nil ,若为 nil 则发生运行时错误。
然后若有虚表则检查虚表合法性。FPC (Delphi 应该也是如此)的实现是虚表中第一项是类实例大小(SizeInt 类型),第二项是其相反数。
验证机制是若第一项为零或两项相加不为零则表示虚表非法。
2017年04月01日 02点04分 3
补充:Debug 模式下还会做一次 as 运算检验对象合法性。
2017年04月01日 06点04分
1