2011-05-06 11 views
6

Estoy intentando crear lo que entiendo para ser una Fábrica de clases en Delphi 2007. Quiero pasar un tipo de clase derivado a una función y hacer que construya un objeto de ese tipo de clase.¿Por qué no se llama al constructor derivado al crear instancias a través de una fábrica de clases de metaclase?

He encontrado algunas buenas referencias, como How can I create an Delphi object from a class reference and ensure constructor execution?, pero todavía no puedo hacer que funcione correctamente. En la prueba siguiente, no puedo hacer que llame al constructor derivado, aunque el depurador me dice que oClass está TMyDerived.

Creo que estoy confundido sobre algo fundamental aquí y podría usar alguna explicación. Gracias.

program ClassFactoryTest; 
{$APPTYPE CONSOLE} 
uses 
    SysUtils; 

// BASE CLASS 
type 
    TMyBase = class(TObject) 
    bBaseFlag : boolean; 
    constructor Create; virtual; 
    end; 
    TMyBaseClass = class of TMyBase; 

constructor TMyBase.Create; 
begin 
    bBaseFlag := false; 
end; 

// DERIVED CLASS 
type 
    TMyDerived = class(TMyBase) 
    bDerivedFlag : boolean; 
    constructor Create; 
    end; 

constructor TMyDerived.Create; 
begin 
    inherited; 
    bDerivedFlag := false; 
end; 

var 
    oClass: TMyBaseClass; 
    oBaseInstance, oDerivedInstance: TMyBase; 
begin 
    oClass := TMyBase; 
    oBaseInstance := oClass.Create; 

    oClass := TMyDerived; 
    oDerivedInstance := oClass.Create; // <-- Still calling Base Class constructor 
end. 

Respuesta

13

se omite la override especificar en el constructor de la clase derivada. (Hubiera esperado una advertencia del compilador sobre la ocultación del método de clase base.) Agregue eso, y debería ver TMyDerived.Create llamado.

TMyDerived = class(TMyBase) 
    bDerivedFlag : boolean; 
    constructor Create; override; 
end; 

Una alternativa, ya que sus constructores tienen ningún parámetro, es renunciar a constructores virtuales y simplemente anular AfterConstruction.

+2

+1, pero ... 'es para renunciar a los constructores virtuales y simplemente anular AfterConstruction'. Urgh qué tan confusamente no estándar. Por favor, quédese con los constructores – Johan

+1

El único problema con el uso de 'AfterConstruction' para esto es que no aclara el intento. Sería fácil crear una subclase y agregar un constructor no reemplazado. Un constructor virtual lo aclara. Dicho esto, si cometió este error, su código no funcionaría, lo que siempre me parece una excelente red de seguridad. –

Cuestiones relacionadas