[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