Egyszerű adatstruktúra

Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2013. november 20-án áttekintett verziótól ; az ellenőrzések 58 szerkesztést igényelnek .

Az egyszerű adatstruktúra ( eng.  plain old data , POD ) egy olyan adattípus a modern, magas szintű programozási nyelvekben , amely mereven meghatározott mezőelrendezéssel rendelkezik a memóriában, amely nem igényel hozzáférési korlátozásokat és automatikus vezérlést . Az ilyen típusú változók egyszerű memóriamásolási rutinokkal másolhatók, mint pl . Ennek ellenkezője a felügyelt adatstruktúra . memcpy

Egy egyszerű adatstruktúra meghatározásának legegyszerűbb módja az ellentmondás. Ha a fordító titokban átrendezi a mezőket a felhasználó elől, vagy adatstruktúra létrehozásakor titokban meghívja a konstruktort , vagy a destruktort hívja a szerkezet megsemmisülésekor , vagy másoláskor - egy speciális másolási eljárás, akkor ez egy kezelt (vagyis , nem egyszerű) szerkezet.

Az egyszerű adatstruktúrák előnyei

Az egyszerű adatstruktúráknak két jellemzője van.

Megjósolható eszköz a memóriában

A fordító saját belátása szerint automatikusan újraépítheti az adatstruktúrát (például megváltoztathatja a mezők sorrendjét. A C++ nyelvben ez csak akkor lehetséges, ha a mezők között nyilvános/privát/védett hozzáférési címke található. Mezősorozat ilyen címkével el nem választva mezőbejelentési sorrendben kell a memóriában elhelyezni). Egy ilyen átalakítás komoly memóriát takaríthat meg, de megszakítja a kompatibilitást. A POD-okban ez az optimalizálás le van tiltva.

Más szóval: a POD jelzésű típusok pontosan úgy vannak elrendezve a memóriában, ahogy a programozó leírta (talán némi igazítással ). Ezért csak POD-ok használhatók két futásidejű könyvtár közötti kommunikációra . Különösen az adatok programról programra, bővítményről beépülő modulra való átvitelére, más programozási nyelven írt kóddal való kommunikációra . Ahhoz, hogy egy összetett fájlfejlécet, például BMP -t, gyorsan lemezre írhasson, formázhatja azt a memóriában, majd egy paranccsal kiírhatja – de az adatszerkezetnek, amelyben a fejlécet alkotjuk, szintén POD-nak kell lennie.

Nincs ellenőrző kód

Ez azt jelenti, hogy egy objektum megjelenésekor nem kell meghívni a konstruktort, másoláskor a hozzárendelési műveletet, megsemmisítéskor pedig a destruktort. Ez viszont a következő előnyökkel jár:

  1. Statikus inicializálás. Ahelyett, hogy a program indításakor meghívnánk a programozó elől rejtett konstruktort , a POD-ok összeállíthatók a program fordítása közben.
  2. Triviális másolás (beleértve a tömbök másolását is) olyan függvényekkel, mint a memcpy.
  3. Ez ismét a programok közötti kommunikáció szempontjából fontos: végül is a memóriakezelőnek nem szabad olyan memóriát kezelnie, amely nem tartozik hozzá.
  4. Csak egyszerű típusok lehetnek union(Pascalban, ill record/case. ).
  5. A mellékhatásokkal járó funkciók (például a következő hívás eredményét befolyásoló rendszerfunkciók GetLastError[1] ) rosszul kompatibilisek az automatikusan kezelt típusokkal.

Nyelvek, amelyeken minden típus egyszerű

C++ nyelven

A C++ nyelvben a POD-t ellentmondás határozza meg. Egy adattípus POD, ha:

A C++ szabvány szerint egy egyszerű adattípus pontosan a leírtak szerint épül fel (és bájtról bájtra teljesen kompatibilis a C szerkezetű memóriaelrendezésben). A fordító az általa leghatékonyabbnak tartott módon átszervezheti a felügyelt struktúrát.

C++11 előtti POD definíció:

Az aggregátum egy tömb vagy egy osztály, amely nem rendelkezik:

Egy aggregátum inicializálható (mint a C-ben) az = {1, 2, 3} formájú listával;

A skalárt:

(vagyis olyan típus, amely nem osztály, tömb vagy hivatkozás)

A POD vagy skalár , vagy más POD-ok tömbje, vagy egy osztály, amely egy aggregátum, és ezen felül:

C++11 nyelven

A „megjósolható eszköz a memóriában” és a „nincs vezérlőkód” hasonló, de eltérő típusú tulajdonságok. Például az adatstruktúra STRRET[ 2] , amely a Windowsban a karakterláncok egyik memóriakezelőből a másikba való átadására szolgál, „ becsomagolható ” vezérlőkódba, de a második tulajdonság, a kiszámítható eszköz megmarad. Ezért a C++11-ben a POD-ok fogalma három részre oszlik.

Egy osztályt "triviális másolatkonstruktorral rendelkező" -nek nevezünk, ha a következők mindegyike igaz:

Az automatikusan generált triviális másolat konstruktor a memmove().

A „triviális alapértelmezett konstruktor/hozzárendelés operátor/mozgatás konstruktor/mozgatás operátor” kifejezések pontosan ugyanígy vannak definiálva.

Egy osztályt "triviális destruktorral rendelkező"-nek nevezünk, ha a következők mindegyike igaz:

Egy ilyen osztály nem igényel megsemmisítést, és az azt tartalmazó memória tisztítás nélkül felszabadítható.

Egy osztályt "triviálisan másolhatónak" mondunk, ha a fenti speciális tagfüggvények mindegyike triviális (kivéve az alapértelmezett konstruktort, amely lehet, hogy nem triviális). A skalárok, valamint a triviálisan másolható objektumok tömbjei szintén triviálisan másolhatók. Az ilyen típusok a következőn keresztül másolhatók memcpy.

Egy osztályt "triviálisnak" nevezünk, ha triviálisan másolható, és van egy triviális alapértelmezett konstruktora is.

Más szóval, egy osztály triviális , ha van benne triviális:

Az osztály szabványos eszköztípus, ha:

Tisztázzuk az utolsó feltételt: a nyelvben nem lehet két különböző, azonos típusú objektum azonos címmel, ami azt jelenti, hogy egy üres (nem statikus mezők nélküli) osztály mérete nem lehet 0 (legalább 1). Mindazonáltal kivételt képez a „B rész a D osztályban : B”, és mérete (ha üres) szigorúan nulla lehet, így nincs „kitöltés” ​​D eleje és első mezője között. Ugyanakkor, ha az első mező típusa is B, a kivétel nem alkalmazható, mivel a (B *) & d és a & (d. field1) különböző azonos típusú objektumokra mutat, és ezért a " padding" szükséges. A fenti lista utolsó feltétele nem jelent mást, mint "a szabványos eszköz osztályaiban az ilyen tömítés tilos".

Az ilyen típusoknak van egy kiszámítható eszköze a memóriában (például egy objektum egészének címe megegyezik az első mező címével, természetesen ugyanazon típusba való újraértelmezés után, pl. to void *), átadható egy másik futásidejű könyvtárnak és más nyelvű programozásnak.

Ekkor a POD  más POD-ok tömbje, vagy skalár, vagy egy triviális osztály egy szabványos eszközzel, amelynek minden nem statikus mezője egyben POD is.

A fordítási időállandókkal és a statikus inicializálással való munkához a C++11 lágyabb koncepcióval rendelkezik - szó szerinti típus . Ugyanis:

POD-ok és "alapértelmezett" és "érték" inicializálás

C++03 óta különbség van T t között; és T t();, valamint új T és új T() között.

Az üres zárójelekkel ellátott verziót "érték inicializálásnak", ezek nélkül pedig "alapértelmezett inicializálásnak" nevezik.

Alapértelmezett inicializálás: ha az alapértelmezett konstruktor triviális, akkor nem történik semmi, szemét marad az objektumban. Ha az alapértelmezett konstruktor nem triviális, akkor végrehajtódik.

Inicializálás érték szerint: ha van kifejezetten megírt alapértelmezett konstruktor, akkor az végrehajtódik. Ha nem (vagyis ha az alapértelmezett konstruktor triviális vagy automatikusan generálódik), akkor először az objektum nullázásra kerül, és csak ezután kerül végrehajtásra a konstruktor (ha nem triviális). A skaláris típusok nullára vannak állítva, ha értékkel inicializálják.

Embarcadero Delphi

Minden típus egyszerű adatszerkezetnek minősül, kivéve:

Jegyzetek

  1. GetLastError archiválva : 2013. december 6. a Wayback Machine -en az MSDN -n
  2. STRRET szerkezet (Windows) . Letöltve: 2013. április 6. Az eredetiből archiválva : 2013. április 18..

Lásd még