[fpc-pascal] Wrong constructor returning the right object

Jeppe Græsdal Johansen jeppe at j-software.dk
Sun Feb 23 15:45:07 CET 2014


Den 23-02-2014 15:26, Mark Morgan Lloyd skrev:
> I think I've sorted this but I'd appreciate being kicked if it looks 
> like I'm doing something badly wrong.
>
> What determines the constructor that's called when an object's created?
>
> I've got a couple of classes defined like this:
>
>   TB5500BaseUnit=
>     class(TObject)
>       constructor Create(enum: integer; mnem: String7; unitIndex: 
> integer; unitDesignate: integer; cc: TObject);
> ..
>
>   TB5500SPOUnit=
>     class (TB5500BaseUnit)
>       constructor Create(enum: integer; mnem: String7; unitIndex: 
> integer; unitDesignate: integer; cc: TObject);
> ..
>
> The actual objects being created are in response to configuration 
> tables and files:
>
> var
>   unitClass: class of TB5500BaseUnit; (* Ancestor of all I/O devices *)
>   u: TB5500BaseUnit;
>   name: string;                       (* For debugging *)
> ..
>
>         unitClass := LookupUnitType( { from device name } );
>         name := unitClass.ClassName;    (* For debugging *)
>         name := '';                     (* Make sure it's wiped *)
>         u := unitClass.Create(Ord(mnem), specs.unitName, 
> specs.unitIndex, specs.designate, self);
>         name := u.ClassName;            (* For debugging *)
>         thisUnit[specs.unitIndex] := u;
>
> If I was trying to create a TB5500SPOUnit I was finding that unitclass 
> was set correctly, and that u was getting a valid type with (later) 
> public methods declared as overrides being available. The odd thing 
> was that TB5500SPOUnit.Create() was not being called, but instead 
> TB5500BaseUnit.Create().
>
> I find that if I explicitly decorate TB5500BaseUnit.Create() as 
> virtual and TB5500SPOUnit.Create() as override then 
> TB5500SPOUnit.Create() is called correctly. I didn't think this was 
> necessary, but on reflection I assume that it's because u is declared 
> as a TB5500BaseUnit: the variable's compile-time rather than run-time 
> class is being used for the constructor unless explicitly overridden.
>
> Is there an obvious way of tiying this up that I'm overlooking?
>
You have forgotten to declare the constructor virtual.



More information about the fpc-pascal mailing list