Recent

Author Topic: "object" types and inheritance  (Read 2915 times)

msieweke

  • Newbie
  • Posts: 2
"object" types and inheritance
« on: May 19, 2014, 02:35:50 am »
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;
type
  delegate = object
    procedure p(i: integer); virtual; abstract;
    constructor init;
  end;
  delegate2 = object( delegate )
    n : integer;
    procedure p(i: integer); virtual;
    constructor init( new_n : integer );
  end;
constructor delegate.init;
begin
end;
constructor delegate2.init( new_n : integer );
begin
  n := 2;
end;
procedure delegate2.p( i: integer );
begin
  writeln( 'delegate2.p: n ', n, ' i ', i );
end;
procedure caller( p : delegate );
begin
  p.p( 3 );
end;
var
  inner : delegate2;
begin
  inner.init( 2 );
  caller( inner );
  inner.p( 8 );
end.

taazz

  • Hero Member
  • *****
  • Posts: 5363
Re: "object" types and inheritance
« Reply #1 on: May 19, 2014, 02:57:07 am »
Don't you need to override one of the inherited method instead of re declaring it as virtual?
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5635
    • wiki
Re: "object" types and inheritance
« Reply #2 on: May 19, 2014, 04:06:59 am »
1) virtual is correct according to doc (surprising, but yes) http://www.freepascal.org/docs-html/ref/refsu26.html#x68-770005.5.2

-------
http://www.freepascal.org/docs-html/ref/refse26.html#x62-690005.1
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.

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?

« Last Edit: May 19, 2014, 04:11:54 am by Martin_fr »

msieweke

  • Newbie
  • Posts: 2
Re: "object" types and inheritance
« Reply #3 on: May 19, 2014, 04:45:09 am »
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.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5635
    • wiki
Re: "object" types and inheritance
« Reply #4 on: May 19, 2014, 05:05:44 am »
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.