L'introduzione di interfacce in una gerarchia di classe esistente in Delphi
-
27-09-2019 - |
Domanda
Ci sono effetti collaterali di cambiare l'antenato di una gerarchia di classi da TObject a TInterfacedObject in modo che possa implementare interfacce a valle della catena di ereditarietà?
ho programmato in Delphi per diversi anni, ma mai incontrato interfacce. Sono diventato abituato a usarle in altre lingue. Ora che sono coinvolto in un progetto Delphi di nuovo mi piacerebbe iniziare a prendere vantaggio di loro, ma so che funzionano un po 'diverso rispetto a Java o C #.
Soluzione
Se hai già il codice esistente utilizzando la classe probabilmente si dovrà modificare un sacco di esso per mantenere i riferimenti alle interfacce invece di istanze di oggetti. Interfacce sono riferimento contati e rilasciati automaticamente, come risultato, qualsiasi riferimento all'istanza implementor diventerà un puntatore non valido.
Altri suggerimenti
Questo funziona bene fino a quando si eredita dalla classe di sotto in alto (in basso?) Della gerarchia. Questo codice garantisce che il vostro nuove classi dont liberarsi - come è il comportamento predefinito di TInterfaceObject - si sono presumibilmente già liberando voi stessi e vogliono preservare questo. Questa attività è in realtà esattamente ciò che TComponent nella VCL fa - supporta le interfacce, ma non è il riferimento contato.
type
TYourAncestor = class( TInterfacedObject )
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
implementation
function TYourAncestor.QueryInterface(const IID: TGUID; out Obj): HResult;
const
E_NOINTERFACE = HResult($80004002);
begin
if GetInterface(IID, Obj) then Result := 0 else Result := E_NOINTERFACE;
end;
function TYourAncestor._AddRef: Integer;
begin
Result := -1 // -1 indicates no reference counting is taking place
end;
function TYourAncestor._Release: Integer;
begin
Result := -1 // -1 indicates no reference counting is taking place
end;
A parte qualche extra byte nella vostra taglia esempio, nessuno. Questo è probabilmente il modo migliore per farlo.