2009-04-21 18 views
21

¿Debería llamar "heredado" en el constructor de una clase derivada de TObject o TPersistent?Uso heredado en el constructor "Crear" de un objeto TObject

constructor TMyObject.Create; 
begin 
inherited Create; // Delphi doc: Do not create instances of TPersistent. Use TPersistent as a base class when declaring objects that are not components, but that need to be saved to a stream or have their properties assigned to other objects.  
VectorNames := TStringList.Create; 
Clear; 
end; 

Respuesta

38

Sí. No hace nada, es cierto, pero es inofensivo. Creo que vale la pena ser consecuente con llamar siempre al constructor heredado, sin verificar si hay, de hecho, una implementación. Algunos dirán que vale la pena llamar a Create heredado porque Embarcadero podría agregar una implementación para TObject.Create en el futuro, pero dudo que esto sea cierto; rompería el código existente que no llama a Create heredado. Aún así, creo que es una buena idea llamarlo solo por la coherencia.

+0

De hecho, es un buen hábito –

+0

"No hace nada" ?? !! ¡Inicia el almacenamiento básico de objetos! Y puede hacer las cosas necesarias definidas en una clase base que está heredando. No llamarlo puede provocar el peor tipo de errores y errores: aquellos que no se dan cuenta de lo que está sucediendo de inmediato. –

+2

IIRC, el almacenamiento básico ya está asignado antes de llamar a su constructor (Crear). – mj2008

13

Siempre hago esto.

Si se reestructuran y se mueven código a un ancestro común, llamando a la heredada Crear tiene las siguientes ventajas:

  1. Si el ancestro común tiene un constructor, no se puede olvidar a llamarlo.
  2. Si el ancestro común tiene un constructor con parámetros diferentes, el compilador lo advierte para esto.
+3

Aunque Craig está en lo cierto, estas son también mis principales razones para invocar Create heredado más que ser consecuente –

2

También puede anular "procedure AfterConstruction". Este procedimiento siempre se llama, sin importar qué tipo de constructor.

public 
    procedure AfterConstruction; override; 
end; 

procedure TfrmListBase.AfterConstruction; 
begin 
    inherited; 
    //your stuff, always initialized, no matter what kind of constructor! 
end; 

Por ejemplo: si desea crear un objeto con un constructor diferente que el TObject.Create normal, como TComponent.Create (AOwner) o un constructor personalizado (sobrecarga), se pueden tener problemas debido a que su la anulación no se llama y (en este caso) su variable "VectorNames" será nula.

+3

Si no se llama al constructor reemplazado, entonces se trata de un error en su clase descendiente. Ese es un problema para el desarrollador de la clase descendiente del que preocuparse, no usted. Y es posible omitir una llamada al AfterConstruction, por la misma razón, puede omitir una llamada al constructor: el descendiente proporciona su propia implementación y omite llamar al método heredado. –

+2

Rob: Si crea una clase de fábrica, que genera descendientes TObject, no puede usar TObject.Create() porque no es virtual! Y si hace un descendiente TComponent en su fábrica: tiene un constructor diferente (Create (AOwner)). Eso es w Deberías usar AfterConstruction: siempre se llama, no importa qué tipo de constructor –

2

Lo llamo, excepto cuando necesito un constructor muy optimizado.

Cuestiones relacionadas