Delphi chiama ereditato su procedure sovrascritte se non esiste una chiamata esplicita

StackOverflow https://stackoverflow.com/questions/53715

  •  09-06-2019
  •  | 
  •  

Domanda

Delphi chiama ereditato su procedure sovrascritte se non c'è una chiamata esplicita nel codice, ad esempio (ereditato;), ho la seguente struttura (dalla super alla sottoclasse)

TForm >> TBaseForm >> TAnyOtherForm

Tutti i moduli nel progetto saranno derivati ​​da TBaseForm, poiché questo avrà tutte le parti di configurazione e distruttive standard utilizzate per ogni modulo (sicurezza, convalida ecc.).

TBaseForm ha procedure onCreate e onDestroy con il codice per farlo, ma se qualcuno (cioè io) dimenticasse di aggiungere ereditato a onCreate su TAnyOtherForm, Delphi lo chiamerebbe per me?Ho trovato riferimenti sul Web che dicono che non è richiesto, ma da nessuna parte dice se viene chiamato se viene omesso dal codice.

Inoltre, se per me chiama ereditato, quando lo chiamerà?

È stato utile?

Soluzione

No, se lasci la chiamata in eredita, non verrà chiamata.Altrimenti non sarebbe possibile sovrascrivere un metodo e ometterne totalmente la versione genitore.

Altri suggerimenti

Vale la pena ricordare che la mancata chiamata ereditata in Destroy di qualsiasi oggetto può causare perdite di memoria.Sono disponibili strumenti per verificarlo nel codice sorgente.

La chiamata ereditata deve essere effettuata esplicitamente.In generale nessun linguaggio chiama automaticamente la funzione ereditata in situazioni equivalenti (costruttori di classi non inclusi).

È facile dimenticare di effettuare la chiamata ereditata in un costruttore di classe.In una situazione del genere, se una classe base deve inizializzare tutti i dati, è in attesa che si verifichi una violazione di accesso.

Forse potresti sovrascrivere DoCreate e DoDestory nella tua classe TBaseForm in modo da poter garantire che parte del codice venga eseguito indipendentemente dall'implementazione delle classi figlie.

// interface

TBaseForm = Class(TForm)
...
Protected
    Procedure DoCreate(Sender : TObject); Override;
End

// implementation

Procedure TBaseForm.DoCreate(Sender : TObject);
Begin
    // do work here

    // let parent call the OnCreate property  
    Inherited DoCreate(Sender);
End;

Inherited deve essere chiamato esplicitamente negli oggetti discendenti così come nell'ereditarietà del formato visivo.Se utilizzi il completamento della classe, viene aggiunto automaticamente ereditato se hai contrassegnato la definizione come override (ma non per reintrodurre).Se stai utilizzando l'ereditarietà del modulo visivo, quando aggiungi un nuovo gestore di eventi tramite l'editor del modulo, verrà aggiunto anche quello ereditato.

Il codice ereditato non viene chiamato implicitamente, come hanno indicato gli altri.Devi chiamarlo esplicitamente.Questo ti dà una certa flessibilità utile.Ad esempio, potresti voler eseguire del codice di pre-elaborazione prima del codice ereditato, quindi eseguire successivamente del codice di post-elaborazione.Potrebbe assomigliare a:

procedure TMyCalcObject.SolveForX;
begin
  ResetCalcState;
  inherited SolveForX;
  PostProcessSolveForX;
end;

NO.Questo è il punto centrale dell'override.

Devi chiamarlo esplicitamente.Ciò consente molta flessibilità, poiché puoi scegliere in quale punto del codice chiamare il metodo ereditato.Ma è anche una grande fonte di bug.È facile dimenticare di chiamare la funzione ereditata e il compilatore non ha modo di sapere se l'hai fatto deliberatamente o te ne sei semplicemente dimenticato.

Dovrebbe esserci una sorta di direttiva "skip_inherited" per dire al compilatore che non vuoi chiamare il metodo ereditato.

Il compilatore segnalerebbe quindi facilmente l'errore se non trovasse né "ereditato" né "skip_inherited".Significherebbe che te ne sei dimenticato.Ma sfortunatamente nessuno in CodeGear ci ha pensato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top