我正在测试以下代码:
type
TPersonA = class
public
procedure Speak;virtual;
end;
TPersonB = class
public
procedure Speak;virtual;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var PersonA: TPersonA;
PersonB : TPersonB;
begin
PersonA := TPersonA.Create;
PersonB := TPersonB.Create;
PersonA := Pointer( PersonB );
PersonA.Speak;
end;
procedure TPersonA.Speak;
begin
ShowMessage('Hello');
end;
procedure TPersonB.Speak;
begin
ShowMessage('Hello again');
end;
end.
因此,如果我使用虚拟方法运行此代码并将 PersonB 的指针传递给 PersonA 并调用 Speak,则执行 PersonB.Speak。
但是,如果我删除两个方法中的 virtual 指令并再次运行,则 delphi 将 PersonA 的方法作为静态执行,因为它的地址将在调用它的地方直接编译到代码中。
所以,当这两种方法都被声明为 virtual 并且我更改了代码时:
PersonA := 指针( PersonB ) ==> PersonA := @PersonB
我遇到了访问冲突。我认为在第一种情况下是在做一个指针指针,但在这种情况下我对 @ 的用法感到困惑。
最佳答案
类型从TObject
派生的变量实际上是指向实例的指针。
所以 Pointer(PersonB)
也是指向实例的指针。但是 @ObjectB
是指向实例的指针的地址。那就是有一个额外的间接级别。
FWIW 这两个选项都是毫无意义的,不会导致任何有用的地方。
至于删除 virtual
指令时的不同行为,使用实例的运行时类型调度虚拟方法,使用实例变量的编译时类型调度非虚拟方法。代码完全运行的事实是由于两个不相关的类具有兼容的 VMT。但这只是实现细节的机会。
关于delphi - @Object 与 Pointer( Object ) 有什么区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51221193/