Tipul de variante

În Delphi 2.0, a fost introdus un nou tip de date puternic, Variant. Practic valoarea sa a fost de a sprijini automatizarea OLE (OLE Automation), unde tipul de date Variant este folosit foarte mult. De fapt, tipul Variant al limbajului Object Pascal este o încapsulare a variantelor OLE. După cum am văzut în curând, implementarea Delphi a variantelor s-a dovedit utilă din punctul de vedere al altor aspecte ale programării. Obiectul Pascal este singurul limbaj compilat în care este introdus un tip de date specializat pentru a lucra cu variante OLE, reprezentate ca fiind dinamice la run-time și statice în timpul compilării.

În Delphi 3, în același scop, a fost introdus un alt tip de date nou, OleVariant, care este complet identic cu tipul Variant, cu excepția faptului că poate conține numai acele tipuri compatibile cu OLE. Mai târziu, în această secțiune, sunt prezentate mai detaliat tipurile de variație și diferențele dintre tipurile de date OleVariant și Variant.

Varianta - schimbare de tip dinamic

Scopul principal al tipului de variantă este de a oferi posibilitatea de a declara o variabilă a cărei tip este necunoscut în momentul compilării. Aceasta înseamnă că tipul actual al unei astfel de variabile se poate modifica în timpul executării programului. De exemplu, următorul program este corect și va fi compilat și tu

să fie umplută fără erori.

V: varianta; // V este o variabilă de tip Variant

V: = 'Delphi este minunat!'; // V conține un șir (tip șir)

V: = 1; // V este un număr întreg (tip Integer)

V: = 123,34; // V este un număr real (tip flotant)

V: = Adevărat; // V - Boolean (tip boolean)

V: = CreateOleObject ("Word.Basic"); // V conține un obiect OLE

Structura de date pentru definirea variantelor

Structura definiției datelor de tip Variant este descrisă în modulul Sistem și arată

după cum urmează:

TVarType = Cuvânt; PVarData = ^ TVarData;

caz Integer al

0: (Reserved1: Word;

caz Integer al

0: (Rezervat2, Rezervat3: Cuvânt;

caz Integer al

varSmallInt: (VSmallInt: SmallInt);

varInteger: (VInteger: Integer);

varSingle: (VSingle: Single);

varDouble: (Vdouble: Double);

varCurrency: (V Currency: Currency);

varDate: (VDate: TDateTime);

varOleStr: (VOleStr: PWideChar);

varDispatch: (VDispatch: Pointer);

varError: (VError: LongWord);

varBoolean: (VBoolean: WordBool);

varUnknown: (Necunoscut: Pointer);

varShortInt: (VShortInt: ShortInt);

varByte: (VByte: Byte);

varWord: (VWord: Word);

varLongWord: (VLongWord: LongWord);

varInt64: (VInt64: Int64);

varString: (VString: Pointer); varAny: (VAny: Pointer); varArray: (VArray: PVarArray); varByRef: (VPointer: Pointer);

1: (VLongs: matrice [0..2] de LongInt);

2: (VWords: array [0..6] din Word);

3: (VBytes: array [0..13] de Byte) Structura TVarData are 16 octeți de memorie. Primele două octeți din această structură conțin un cuvânt a cărui valoare determină tipul de date la care se referă opțiunea. Mai jos sunt valorile specifice care corespund diferitelor tipuri de date care pot fi plasate în câmpul VType al intrării TVarData. Următorii 6 octeți din înregistrare nu sunt utilizați. Ultimii 8 octeți conțin fie date actuale, fie un pointer la datele reprezentate de această variantă. Trebuie remarcat faptul că această structură îndeplinește exact cerințele pentru implementarea variantelor OLE.

varEmpty = $ 0000; varNull = $ 0001; varSmallint = $ 0002; varInteger = $ 0003; varSingle = $ 0004; varDouble = $ 0005; varCurrency = $ 0006; varDate = $ 0007; varOleStr = $ 0008; varDispatch = $ 0009; varError = $ 000A; varBoolean = $ 000B; varVariant = $ 000C; varUnknown = $ 000D;

După cum puteți vedea din codul de mai sus, varianta nu poate conține o referință la datele de tip Pointer sau clasă.

Din descrierea structurii înregistrării TVarData, se poate observa că poate deține într-adevăr date de orice tip. Este necesar să se distingă intrarea mai sus menționată a datelor TVarData de la datele efective de tip Variant. Deși compoziția variabilă și datele de tip Variant (varianta) sunt externe similare în scopul lor, ele reprezintă două construcții complet diferite. Înregistrarea TVarData vă permite să stocați date de diferite tipuri în aceeași zonă de memorie (cum ar fi uniunile C / C ++ union). Mai multe informații detaliate despre acest subiect sunt date mai târziu în acest capitol. Declarația cazului din descrierea înregistrării TVarData servește pentru a determina tipurile de date pe care o variantă le poate reprezenta. Deci, dacă câmpul VType conține valoarea varInteger, numai patru din cei opt octeți ai datelor de înregistrare vor conține variabila stocată a întregii valori. În mod similar, dacă câmpul VType conține valoarea var-byte, numai unul din cei opt octeți din zona de date va fi utilizat pentru a stoca valoarea.

Rețineți că dacă VType conține valoarea varString, atunci opt octeți de date din înregistrare nu conțin un șir real, ci doar un pointer la acesta. Acest lucru este foarte important pentru a înțelege, deoarece atunci când lucrați cu opțiuni, puteți accesa direct valorile din orice câmp, după cum se arată în exemplul de mai jos.

Trebuie să știți că o astfel de utilizare a variantei este un joc periculos, deoarece, de exemplu, puteți distruge cu ușurință un pointer unui șir sau alt obiect cu o durată de viață controlată. Ca urmare, obiectul va deveni inaccesibil proceselor de "colectare a gunoiului", ceea ce va duce la pierderea memoriei și pierderea altor resurse de aplicație. Pentru mai multe informații despre procesul de colectare a gunoiului, vedeți următoarea secțiune.







Articole similare

Trimiteți-le prietenilor: