Forum > General

"object" types and inheritance


I'm trying to use "object" types to implement a "delegate" concept.  A delegate is a function pointer with associated data.  I used simple inheritance, but the code doesn't behave as I expect.  The code below produces this output:

delegate2.p: n 2 i 8
delegate2.p: n 214704 i 3

I think both lines should print the same.  It appears that the object pointer passed by "caller()" is not valid.  What am I missing here?

program objecttest;
  delegate = object
    procedure p(i: integer); virtual; abstract;
    constructor init;
  delegate2 = object( delegate )
    n : integer;
    procedure p(i: integer); virtual;
    constructor init( new_n : integer );
constructor delegate.init;
constructor delegate2.init( new_n : integer );
  n := 2;
procedure delegate2.p( i: integer );
  writeln( 'delegate2.p: n ', n, ' i ', i );
procedure caller( p : delegate );
  p.p( 3 );
  inner : delegate2;
  inner.init( 2 );
  caller( inner );
  inner.p( 8 );

Don't you need to override one of the inherited method instead of re declaring it as virtual?

1) virtual is correct according to doc (surprising, but yes)


--- Quote ---Objects should be treated as a special kind of record. The record contains all the fields that are declared in the objects definition, and pointers to the methods that are associated to the objects’ type.
--- End quote ---

My understanding.

The object is a record.  That also implies all data is passed as COPY, not as reference)

The param to Caller is a record of type delegate. (When this is compiled, there is no knowledge if other units have inherited objects, that have more fields / So it can only hold the fields of delegate)

When caller is called, only the "common" part (only delegate) is passed. "n" is not passed (it could not be stored in a delegate.

As for the virtual methods: Since both (delegate and delegate2) have a VMT, the correct VMT is passed, and dellegate2.p is called from caller.

Therefore you are lucky it is just wrong data. IT could be an access violation. You are accessing data outside of the object.

Why object, why not class?

Thank you for the explanation.  With the code changed to use pointers, it worked as expected.

I chose objects because they're allocated on the stack - simpler to use, in theory.

They do unfortunately have those pitfalls.

You should compile with -gh (heaptrc), in order to spot, if you forget to free an object (as in instantiated class).
As class-objects must be freed by hand.


[0] Message Index

Go to full version