Jednoduchá datová struktura ( angl. plain old data , POD ) je datový typ v moderních programovacích jazycích na vysoké úrovni , který má pevně definované uspořádání polí v paměti, které nevyžaduje omezení přístupu a automatické řízení . Proměnné tohoto typu lze kopírovat pomocí jednoduchých rutin pro kopírování paměti, jako je . Opakem je spravovaná datová struktura . memcpy
Nejjednodušší způsob, jak definovat jednoduchou datovou strukturu, je kontradikce. Pokud kompilátor tajně přeuspořádá pole od uživatele nebo při vytváření datové struktury tajně zavolá konstruktor nebo zavolá destruktor , když je struktura zničena , nebo při kopírování - speciální procedura kopírování, pak se jedná o spravovanou (tj. , není jednoduchá) struktura.
Jednoduché datové struktury mají dvě vlastnosti.
Kompilátor může podle svého uvážení automaticky přestavět datovou strukturu (například změnit pořadí polí. V jazyce C++ je to možné pouze v případě, že mezi poli je označení public/private/protected access. Sled polí neoddělené takovým štítkem musí být uloženy v paměti v pořadí deklarace polí). Taková restrukturalizace může vážně ušetřit paměť, ale naruší kompatibilitu. V PODech je tato optimalizace zakázána.
Jinými slovy: typy označené POD jsou v paměti uspořádány přesně tak, jak popsal programátor (možná s určitým zarovnáním ). Proto lze ke komunikaci mezi dvěma runtime knihovnami použít pouze PODy . Zejména pro přenos dat z programu do programu, z pluginu do pluginu, pro komunikaci s kódem napsaným v jiném programovacím jazyce . Chcete-li rychle zapsat složitou hlavičku souboru, jako je BMP , na disk , můžete ji vytvořit v paměti a poté ji zapsat jedním příkazem - ale datová struktura, ve které tvoříme hlavičku, musí být také POD.
To znamená, že když se objeví objekt, nemusíte volat konstruktor, při kopírování operaci přiřazení a při ničení destruktor. To zase poskytuje následující výhody:
V C++ je POD definován protikladem. Datovým typem je POD, pokud:
Podle standardu C++ je jednoduchý datový typ strukturován přesně tak, jak je popsáno (a je plně kompatibilní bajt po bajtu v rozložení paměti se strukturou C). Kompilátor může reorganizovat spravovanou strukturu způsobem, který považuje za nejefektivnější.
Definice POD před C++11:
Agregát je buď pole nebo třída, která nemá:
Agregát lze inicializovat (jako v C) se seznamem ve tvaru = {1, 2, 3};
Skalár se nazývá:
(tj. typ, který není třídou, polem nebo odkazem)
POD je buď skalární , nebo pole jiných PODů nebo třída, která je agregovaná, a navíc:
"Předvídatelné zařízení v paměti" a "žádný řídicí kód" jsou podobné, ale mají odlišné vlastnosti. Například datovou strukturu STRRET[ 2] , která se ve Windows používá k předávání řetězců z jednoho správce paměti do druhého, lze „ zabalit “ do řídicího kódu, ale druhá vlastnost, předvídatelné zařízení, zůstává. Proto je koncept PODů v C++11 rozdělen do tří.
Třída se nazývá „s triviálním kopírovacím konstruktorem“, pokud platí všechny následující podmínky:
Automaticky generovaný konstruktor triviální kopie je memmove().
Termíny „mít triviální výchozí konstruktor/operátor přiřazení/konstruktor přesunu/operátor přesunu“ jsou definovány přesně stejným způsobem.
Třída se nazývá „mající triviální destruktor“, pokud platí všechny následující podmínky:
Taková třída nevyžaduje zničení a paměť, která ji obsahuje, může být uvolněna, aniž by byla vyčištěna.
O třídě se říká, že je „triviálně kopírovatelná“, pokud jsou všechny výše uvedené speciální členské funkce triviální (kromě výchozího konstruktoru, který může být netriviální). Skaláry, stejně jako pole triviálně kopírovatelných objektů, jsou také triviálně kopírovatelné. Takové typy lze kopírovat přes memcpy.
Třída se nazývá "triviální", pokud je triviálně kopírovatelná a má také triviální výchozí konstruktor.
Jinými slovy, třída je triviální , pokud má triviální:
Třída je standardní typ zařízení, pokud:
Ujasněme si poslední podmínku: v jazyce nemohou existovat dva různé objekty stejného typu se stejnou adresou, což znamená, že velikost prázdné třídy (bez nestatických polí) nemůže být 0 (alespoň 1). Výjimka je však učiněna pro "část B ve třídě D : B" a její velikost (pokud je prázdná) může být striktně nulová, což vede k tomu, že mezi začátkem D a jejím prvním polem nebude žádná "výplň". Ale zároveň, pokud je typ prvního pole také B, výjimku nelze použít, protože (B *) & d a & (d. pole1) ukazují na různé objekty stejného typu, a proto " vycpávka“ je potřeba. Poslední podmínka z výše uvedeného seznamu neznamená nic jiného než „ve třídách standardního zařízení je takové těsnění zakázáno“.
Takové typy mají v paměti předvídatelné zařízení (například adresa objektu jako celku je stejná jako adresa jeho prvního pole, přirozeně, po reinterpret_cast na stejný typ, například pro void *), mohou být předán do jiné run-time knihovny a do jiných jazyků programování.
Pak je POD polem dalších PODů, nebo skalární, nebo triviální třída se standardním zařízením, jejichž všechna nestatická pole jsou také PODy.
Pro práci s konstantami v době kompilace a statickou inicializací má C++11 měkčí koncept – typ literal . A to:
Od C++03 existuje rozdíl mezi T t; a Tt();, stejně jako mezi novým T a novým T().
Verze s prázdnými závorkami se nazývá „inicializace hodnoty“ a bez nich se nazývá „výchozí inicializace“.
Výchozí inicializace: pokud je výchozí konstruktor triviální, pak se nic nedělá, v objektu zůstává smetí. Pokud výchozí konstruktor není triviální, provede se.
Inicializace hodnotou: pokud existuje explicitně napsaný výchozí konstruktor, pak se provede. Pokud ne (tj. pokud je výchozí konstruktor triviální nebo generován automaticky), pak je objekt nejprve vynulován a teprve poté je konstruktor proveden (pokud je netriviální). Skalární typy jsou při inicializaci hodnotou nastaveny na nulu.
Všechny typy jsou považovány za jednoduché datové struktury kromě: