2012-02-14 12 views
6

volevo solo porre una semplice domanda - ho una classe derivata da TLabel come segue:ignorato e il costruttore non override

TMyLabel = class (TLabel) 
    ... 
    constructor Create(AOwner: TComponent); override; 
end; 

constructor TMyLabel.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 
    { some code } 
end; 

Ora, Delphi mi permette di compilare entrambe le versioni con e senza l'di override . Potresti spiegare quali sono le differenze? Oltre a non essere in grado di richiedere i miei parametri in Create() quando ha sostituito. Grazie

Modifica: Che cosa intendo è: qual è la differenza tra un virtual e un costruttore non virtuale di base-discendente? Posso sempre chiamare il costruttore ereditato da inherited Create(), quindi qual è il punto?

+0

possibile duplicato di [È necessario inserire le parole di overload o override dopo la dichiarazione del costruttore nella classe derivata?] (Http://stackoverflow.com/questions/360597/need-i-to-put-overload-or-override -words-after-the-constructor-declaration-in-de) –

+0

Il compilatore ti avvisa se non lo fai, giusto? dal duplicato collegato; "Se non lo fai, il compilatore probabilmente ti avviserà che il costruttore di TMinMatrix sta" nascondendo "il costruttore di TMatrix." - Devo ancora imbattersi in un BISOGNO pratico per nascondere un costruttore di componenti, e TCOmponent in particolare sembra fare affidamento su un corretto comportamento virtuale per Costruttori e Distruttori, quindi in genere, con TComponent, è in realtà vicino a un errore. –

+0

Sì, lo fa. Potrebbe essere "nascosto" nel senso che non è _direttamente_ discendente, ma dal momento che lo chiamo per 'inherited' comunque, fa alcuna differenza? –

risposta

9

I costruttori virtuali consentono l'istanziazione polimorfica degli oggetti. Il classico esempio di questo è il meccanismo di streaming .dfm di Delphi.

Il codice che legge i file .dfm e le forme di istanze non sa al momento della compilazione quali classi utilizzare. La decisione viene posticipata al runtime quando può essere eseguita correttamente, cioè quando viene letto il file .dfm. Inoltre, è possibile ottenere il meccanismo del file .dfm per creare componenti personalizzati che non fanno parte del VCL e quindi questo meccanismo .dfm deve essere in grado di creare istanze corrette di classi che non fanno parte del VCL.

Il costruttore per TComponent è dichiarato così:

constructor Create(AOwner: TComponent); virtual; 

Per un componente di prendere parte a questo meccanismo si deve dichiarare il suo costruttore con la direttiva override.

L'altra chiave del processo è riferimenti di classe. Per esempio

type 
    TComponentClass = class of TComponent; 

Il codice che crea componenti durante la lettura di file DFM, grosso modo, assomiglia a questo:

var 
    ComponentClass: TComponentClass; 
    Component, Owner: TComponent; 
.... 
ComponentClass = FindComponentClass(ReadComponentClassName); 
Component := ComponentClass.Create(Owner); 

Ora, se il meccanismo non ha utilizzato costruttori virtuali poi il costruttore che sarebbe stato chiamato sarebbe TComponent.Create. E così il tuo costruttore, TMyLabel.Create non verrebbe mai chiamato.

Ecco perché è necessario includere la direttiva di sovrascrittura sui costruttori quando derivano da TComponent.

+0

Grazie. Tuttavia, nel caso volessi consentire ulteriori derivazioni del 'TMyLabel' E volevo specificare più parametri al momento della creazione, sarebbe possibile a tutti? –

+0

@MartinMelka No, questo non è possibile se si ha intenzione di avere il meccanismo .dfm che istanzia l'etichetta. Chiamerà sempre il costruttore virtuale con il singolo parametro. Probabilmente dovresti semplicemente andare avanti con quel costruttore e aggiungere un metodo o proprietà per permettere che i tuoi parametri extra vengano forniti dopo la creazione. –

+0

Ho pensato così, grazie per averlo chiarito –

2

Bene, se ricordo Delphi correttamente (che era un po 'di tempo fa, anche se era un buon momento :)) quando il costruttore è sovrascritto, sarete in grado di chiamarlo tramite riferimenti di classe (vedi this spec come esempio).

+0

I costruttori virtuali corretti e sovrascritti potrebbero essere richiamati dalle fabbriche di classi che conoscono solo la classe base in cui il costruttore è stato dichiarato per la prima volta. –

Problemi correlati