Delphi @Object和指针(Object)有什么区别?
我正在测试以下代码:Delphi @Object和指针(Object)有什么区别?,delphi,Delphi,我正在测试以下代码: type TPersonA = class public procedure Speak;virtual; end; TPersonB = class public procedure Speak;virtual; end; TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); priv
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.
因此,如果我使用virtual方法运行此代码,并将PersonB指针传递给PersonA并调用Speak,则PersonB.Speak将被执行
但是,如果我删除这两个方法中的virtual指令并再次运行,那么delphi将以静态方式执行PersonA方法,因为它的地址将直接编译到调用它的地方的代码中
因此,当两个方法都声明为虚拟时,我更改了代码:
PersonA:=指针(PersonB)==>PersonA:=@PersonB
我违反了访问权限。我想在第一种情况下是指针的指针,但在这种情况下,我会混淆@的用法。
指针(对象)
是类型转换,@Object
是对象的地址。换句话说@Object
指针(Object)
。当您使用指针(对象)
时,您不会得到指向对象的指针,而是得到原始指针值 其类型从TObject
派生的变量实际上是指向实例的指针
所以指针(PersonB)
也是指向实例的指针。但是@ObjectB
是指向实例的指针的地址。也就是说,有一个额外的间接层次
FWIW这两个选项都是毫无意义的,不会带来任何有用的结果
对于删除
virtual
指令时的不同行为,使用实例的运行时类型调度虚拟方法,使用实例变量的编译时类型调度非虚拟方法。代码运行的原因是两个不相关的类具有兼容的VMT。但这只是一个实施细节的机会 让我们做一个简单的图表(地址由以下部分组成):
Obj
是一个变量。它是一个对象引用,这意味着它实际上是指向实例的指针
如果采用@Obj
,则采用变量的地址。它的类型是指针
所以你得到了@Obj=Pointer($12345600)
如果将Obj
转换为Pointer
作为Pointer(Obj)
,则获得变量指向的实例的地址。它的类型也是指针
所以你得到了指针(Obj)=指针($45680000)
您甚至可以测试这一点:
if @Obj = Obj then
Writeln('Same')
else
Writeln('Different');
if Pointer(Obj) = Obj then
Writeln('Same')
else
Writeln('Different');
你应该得到:
Different
Same
编辑
我将Object
更改为Obj
,因为Object
在Delphi中是一个保留字
有关指针的更多信息,请参阅我的文章: 否@Object是双指针,是指向对象实例的指针的地址。@David Heffernan和where在我的回答中说了相反的话:“当你使用指针(Object)时,你没有得到指向对象的指针”。那是错误的。指针(Object)是指向对象实例的指针。它是实例的地址。无论如何,这真的不清楚。当你使用object这个词时,不清楚你是指一个变量还是一个类实例的一般术语。事实上,尽管我没有投反对票,但我的第一反应与David的相似:你的措辞没有那么清楚。或者这一部分。“
@Object
正在获取对象的地址”。那是错误的。这是对象的地址
本身就是对象的地址。祝贺达到500k代表!你离乔恩·斯基特不远!非常感谢您的解释和链接页面,这是迄今为止我看到的最完整的解释。
Different
Same