alancc
alancc

Reputation: 799

Can I use Pointer to a Class?

I am using Delphi XE3. And after studying the post Delphi - Maintaining Self References to an Object , I understand that a variable of a class type is actually a pointer that references an object.

Therefore, I write the following code to test that, as follows:

TMyClass = class
public
  constructor Create(Name: string);
  destructor Destroy;

  function GetName: string;

private
  FName: string;
end;

PMyClass = ^TMyClass;

constructor TMyClass.Create(Name: string);
begin
  FName := Name;
end;

destructor TMyClass.Destroy;
begin

end;

function TMyClass.GetName: string;
begin
  Result := FName;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Item: TMyClass;
  P: PMyClass;
begin
  Item := TMyClass.Create('Jim');

  P := PMyClass(Item);

  OutputDebugString(PWideChar(Format('Address of object: %x; Address of variable Item: %x; Value of P: %x;',
                            [Integer(Item), Integer(@Item), Integer(P)])));

  OutputDebugString(PWideChar(Format('Name is %s', [Item.GetName()])));
  OutputDebugString(PWideChar(Format('Name is %s', [P.GetName()])));
end;

In my code, using PMyClass(Item) seems also get the object address, since Integer(PMyClass(Item)) is same as Integer(Item). However, it seems that with the pointer to the object, I cannot invoke any method, both P.GetName() and P^.GetName() will cause access violation. Why?

And my question is, whether I can use pointer to class in programming. Also whether it is necessary to use pointer to class since a variable of a class type has already held the object address.

Upvotes: 3

Views: 444

Answers (2)

MBo
MBo

Reputation: 80107

Item already is pointer to the instance of TMyClass and you don't need to introduce excessive level of adressing.

NativeInt(Item) gives you the number representation of the address. To get the same representation from P, with proper type casting, you need to use P = @Item and NativeInt(P^)

I don't see how pointers might be useful for your task.... BTW, what is your real problem?

Upvotes: 0

David Heffernan
David Heffernan

Reputation: 612794

PMyClass(Item)

This cast is wrong. Because Item is TMyClass but PMyClass is ^TMyClass. Item cannot be both TMyClass and ^TMyClass.

The invalid cast is why you encounter the access violation.

If you really did want to obtain a value that was ^TMyClass then you would need to take the address of a TMyClass value. An example from your code would be @Item. So, Item is TMyClass, hence @Item is ^TMyClass.

There are situations where ^TMyClass might be useful, but they are not apparent in any of the code you present. For instance, you might use a variable of type ^TMyClass to hold a reference to a variable of type TMyClass. In other words, the standard scenario where pointers are useful.

Upvotes: 5

Related Questions