Pregunta

I have set up a pointer which I want to point to a component but the component it points to won't be the same one every time the procedure is called which it is simply declared as a 'Pointer'. Here is the code where the pointer is pointed to a component.

Procedure DestroyConnection(Component,ID,Connections:Integer);
Var
ComponentPtr: Pointer;

begin

if Component = 1 then
  ComponentPtr := Cell;

if Component = 2 then
   ComponentPtr := Bulb;

And here is the code where the pointer is reused.

Procedure DestroyLink(Ptr:Pointer; ID:Integer);
var
Component: ^TObject;
begin
Component := Ptr;
Component.Connected := False;

I get an undeclared identifier error on the line:

 Component.Connected := False;

How would I be able to access the component that the pointer points to in the procedure DestroyLink? Sorry if I'm not making much sense :S

¿Fue útil?

Solución

Your variable Component is a pointer to TObject. And since TObject does not have a member named Connected, that is why the compiler objects.

What's more, you have one level of indirection too many. A variable of type TObject, or indeed any Delphi class is already a reference. It is already a pointer. Which is why your assignment to ComponentPtr does not use the @ operator. It doesn't need to take the address since the reference already is an address.

You need to change DestroyLink to match. You need a variable that is not a pointer to a reference, but a variable of whatever the actual type of the object is. For example, suppose the type that defined the Connected property was TMyComponent then your code should be:

var
  Component: TMyComponent;
....
Component := TMyComponent(Ptr);
Component.Connected := False;

Or even simpler would be to change the type of the variable from Pointer to TObject. And then pass around TObject instead of Pointer. Then your code could read:

Procedure DestroyConnection(Component,ID,Connections:Integer);
Var
  Obj: TObject;
begin
  case Component of
  1:
    Obj := Cell;
  2:
    Obj := Bulb;
  ....

And then:

procedure DoSomethingWithObject(Obj: TObject);
begin
  if Obj is TCell then
    TCell(Obj).Connected := False;
  if Obj is TBulb then
    TBulb(Obj).SomeOtherProperty := SomeValue;
end;

If you had a common base class for all of these objects then you could declare your variable to be of that type. And you could then use virtual functions and polymorphism which I think would lead to much simpler and clearer code.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top