On Mon, Jun 10, 2019 at 3:31 PM Ryan Joseph <generic...@gmail.com> wrote:

> Sorry, if I dereference the size is still of TBase. I don’t think “result"
> is actually changing depending on the class type. This may have something
> to do with the way new works though. How can we fix this?
>

It's because Initialize isn't virtual (and can't be), meaning your code
really just creates a PBase and then hard-casts it to a PChild.

If you really want to use objects in that kind of way though, here's a
general example that works and doesn't leak memory:

program Test;

{$mode ObjFPC}
{$modeswitch AutoDeref}

type
  PBase = ^TBase;

  TBase = object
  public
    I: Int64;
    constructor Initialize;
    class function Create: PBase; static; inline;
    procedure Free;
  end;

  constructor TBase.Initialize;
  begin
    WriteLn('Base!');
    I := 12;
  end;

  class function TBase.Create: PBase;
  begin
    New(Result, Initialize);
  end;

  procedure TBase.Free;
  begin
    if Assigned(@Self) then begin
      WriteLn('Size: ', SizeOf(Self));
      FreeMem(@Self, SizeOf(Self));
    end;
  end;

type
  PChild = ^TChild;

  TChild = object(TBase)
  public
    S: String[5];
    constructor Initialize;
    class function Create: PChild; static; inline;
  end;

  constructor TChild.Initialize;
  begin
    inherited Initialize;
    WriteLn('Child!');
    S := 'hello';
  end;

  class function TChild.Create: PChild;
  begin
    New(Result, Initialize);
  end;

var
  PB: PBase;
  PC: PChild;

begin
  PB := TBase.Create;
  WriteLn(PB.I);
  PB.Free;
  PC := TChild.Create;
  WriteLn(PC.I);
  WriteLn(PC.S);
  PC.Free;
end.
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to