2016-07-15 321 views
7

Ho questo codice nella libreria Delphi Detours che sto cercando di porto:Delphi parola chiave "default" con i tipi di record in vecchie versioni di Delphi

type 
    TInstruction = record 
    Archi: Byte; { CPUX32 or CPUX64 ! } 
    AddrMode: Byte; { Address Mode } 
    Addr: PByte; 
    VirtualAddr: PByte; 
    NextInst: PByte; { Pointer to the Next Instruction } 
    OpCode: Byte; { OpCode Value } 
    OpType: Byte; 
    OpKind: Byte; 
    OpTable: Byte; { tbOneByte,tbTwoByte,... } 
    OperandFlags: Byte; 
    Prefixes: Word; { Sets of Prf_xxx } 
    ... 
    end; 

var 
    Inst: TInstruction; 
begin 
    ... 
    Inst := default (TInstruction); // <- 
    Inst.Archi := CPUX; 
    Pvt := PPointer(AIntf)^; // vTable ! 
    PCode := PPointer(Pvt + Offset)^; // Code Entry ! 
    Inst.NextInst := PCode; 
    ... 
end; 

Che cosa significa il "default" parola chiave fare? Mi assumo qualcosa di simile:

FillChar(Inst, SizeOf(TInstruction), 0); 

è la mia ipotesi è corretta?

+0

Definisce/inizializza anche i campi dei tipi gestiti. –

+0

@LURD, posso capire la parte "inizializza". ma quando finisce la variabile? – zig

+0

@zig, ad esempio, cancellazione della memoria da matrici e matrici dinamiche, se il record cancellato era l'ultimo riferimento. Un altro esempio è lo scollegamento degli oggetti conteggio di riferimento di tipo 'interface'. vedi docwiki.embarcadero.com/Libraries/XE7/en/System.Finalize –

risposta

13

Default() è una funzione intrinseca non documentata introdotta per supportare i generici. La progettazione di farmaci generici Delphi è stato fortemente ispirato generici .net e si potrebbe trarre beneficio dalla lettura della documentazione analoga per NET: https://msdn.microsoft.com/en-GB/library/xwth0h0d.aspx

Lo scopo della Default() è quello di consentire al default inizializzare una variabile. Quando si lavora con tipi generici Default(), è possibile farlo per una variabile il cui tipo è generico.

Se si desidera replicare il comportamento del Default() effettuare le seguenti operazioni:

Finalize(Inst); 
FillChar(Inst, SizeOf(Inst), 0); 

è necessario La chiamata a Finalize nel caso in cui il tipo è gestito. Questo è se il tipo è gestito, o contiene membri che sono gestiti. I tipi gestiti includono stringhe, matrici dinamiche, interfacce, varianti, metodi anonimi, ecc.

Se il tipo non contiene tipi gestiti, la chiamata a Finalize può essere omessa. Non fa male però includerlo, perché il compilatore lo eliminerà se non necessario. Se puoi essere sicuro al 100% che a nessun tipo gestito è stato assegnato un valore, potresti anche omettere quella chiamata.

inizializzazione predefinito significa la seguente:

  • zero per i tipi numerici.
  • Il valore con lo zero ordinale per i tipi enumerati.
  • False per tipi booleani.
  • #0 per tipi di caratteri.
  • La stringa vuota per le stringhe.
  • La variante vuota per Variant.
  • nil per classi, matrici dinamiche, interfacce e metodi anonimi.
+0

Il suggerimento del compilatore: '[Suggerimento] DDetours.pas (1919): espressione non necessita di inizializzazione/finalizzazione'. Quindi, dovrei semplicemente rimuovere 'Finalize (Inst);' o dovrei disattivare il suggerimento? – zig

+0

Fino a voi. Fallo in entrambi i casi Probabilmente eliminerei la finalizzazione. –