What is the difference of @Object vs Pointer( Object )?

  • A+
Category:Languages

I was testing this following code:

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. 

So if a run this code with methods as virtual and pass a pointer of PersonB to PersonA and call the Speak, PersonB.Speak is executed.

However, if i delete the virtual directive in both methods and run again then delphi executes the method of PersonA as static, cause it's adress will be compiled directly into the code at the place it was called.

So, when both methods were declared as virtual and i changed the code:

PersonA := Pointer( PersonB ) ==> PersonA := @PersonB

I got into a access violation. I think was doing in the first case a pointer of pointer but i've gotten confuse with the usage of @ in that case.

 


A variable whose type descends from TObject is actually a pointer to the instance.

So Pointer(PersonB) is also pointer to the instance. But @ObjectB is the address of a pointer to the instance. That is there is an extra level of indirection.

FWIW both of these two options are meaningless and will not lead anywhere useful.

As for the different behaviour when you remove the virtual directive, a virtual method is dispatched using the runtime type of the instance, a non-virtual method is dispatched using the compile time type of the instance variable. The fact that the code runs at all is due to the two unrelated classes having compatible VMTs. But that's just a chance of implementation detail.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: