[fpc-devel] Generics - a general question

AvP downloaditweb at googlemail.com
Fri Nov 18 18:31:58 CET 2011


I just made a first attempt to use generics. Trying different things I figured
out that the appended code compiles without any error message in FPC
2.6.0RC1

1. Is this behavior intended (generic objects)?
   I didn't find anything like that in the docs

2. Replacing "object" at (1) with "class" gives an error when compiling

3. In my case the specialization should only work if _ResType is TType or
derived, as certain fields and functions/procedures are read / executed

Is there currently a way to do this typesafe (my version is a hack, I believe)
?
If not, maybe this would be an interesting feature for FPC.

Maybe I'm trying to do the manager in a way, that isn't the right one - other
suggestions are welcome - but as this is on a developer maillist (I
know), my question mainly concerns the general generics part.

Thanks
A.v.P.

============================================================
program Test;

{$mode objfpc}{$H+}

uses Classes;

{$R *.res}

type

 TType = object
     RefCount : Word;
     constructor Init;
     destructor Done;
     function GetCount : Word;
 end;

 // manages a list of _ResType-Objects
 generic TManager<_ResType> = object  //(1)
       // _ResType must be TType or detrieved, howto define this??
   type
     PResType = ^_ResType;
   public
     constructor Create;
     destructor Destroy;
     function GetRefCount : Word;
     // stuff to manage Resource-array
   private
     Resource : array of PResType;   // array of pointer to specialized type
of generic
 end;

 TResManager = specialize TManager<TType>;

 constructor TType.Init;
 begin
   RefCount := 3;
   WriteLn('TType.Init done...');
 end;

 destructor TType.Done;
 begin
   WriteLn('TType.Done...');
 end;

 function TType.GetCount : Word;
 begin
   Result := Self.RefCount;
 end;



 constructor TManager.Create;
 begin
   SetLength(Resource, 2);
   Resource[0]^.Init;  // No problem here
   WriteLn('Manager.Create done...');
 end;

 destructor TManager.Destroy;
 begin
   Resource[0]^.Done;  // No problem here
   WriteLn('Manager.Destroy done...');
 end;

 function TManager.GetRefCount : Word;
 begin
   Result := Resource[0]^.RefCount;          // direct access
   // or:
   //Result := Resource[0]^.GetCount;        // helper function
 end;

Var
 TT : TResManager;
begin
 TT.Create;
 WriteLn(TT.GetRefCount);
// if commented then 'no problem' else 'Access violation' 
 TT.Destroy;
end.

============================================================

An unhandled exception occurred at $0000000000411D90 :
EAccessViolation : Access violation
 $0000000000411D90 line 66 of Test.lpr
 $0000000000411DF6 line 76 of Test.lpr



More information about the fpc-devel mailing list