En enkel datastruktur ( eng. plain old data , POD ) är en datatyp i moderna högnivåprogrammeringsspråk som har ett strikt definierat arrangemang av fält i minnet som inte kräver åtkomstbegränsningar och automatisk kontroll . Variabler av denna typ kan kopieras med enkla minneskopieringsrutiner som . Motsatsen är en hanterad datastruktur . memcpy
Det enklaste sättet att definiera en enkel datastruktur är genom motsägelse. Om kompilatorn i hemlighet ordnar om fälten från användaren, eller när man skapar en datastruktur, i hemlighet anropar konstruktorn eller anropar destruktorn när strukturen förstörs , eller när man kopierar - en speciell kopieringsprocedure, så är detta en hanterad (dvs. , inte enkel) struktur.
Enkla datastrukturer har två funktioner.
Kompilatorn kan automatiskt bygga om datastrukturen efter eget gottfinnande (till exempel ändra ordningen på fälten. I C++-språket är detta endast möjligt om det finns en offentlig/privat/skyddad åtkomstetikett mellan fälten. En sekvens av fält som inte är åtskilda av en sådan etikett måste placeras i minnet i fältdeklarationsordning). En sådan omstrukturering kan på allvar spara minne, men bryter kompatibiliteten. I POD:er är denna optimering inaktiverad.
Med andra ord: typer märkta med POD är ordnade i minnet exakt som programmeraren beskrev (kanske med viss justering ). Därför kan endast POD:er användas för att kommunicera mellan två runtime-bibliotek . I synnerhet för att överföra data från program till program, från plugin till plugin, för att kommunicera med kod skriven på ett annat programmeringsspråk . För att snabbt skriva en komplex filhuvud som BMP till disk kan du skapa den i minnet och sedan skriva den med ett kommando - men datastrukturen som vi bildar rubriken i måste också vara en POD.
Det betyder att när ett objekt dyker upp behöver du inte anropa konstruktorn, vid kopiering, tilldelningsoperationen och vid förstöring, förstöraren. Detta ger i sin tur följande fördelar:
I C++ definieras POD av motsägelse. En datatyp är en POD om:
Enligt C++-standarden är en enkel datatyp strukturerad exakt som beskrivits (och är helt kompatibel byte-för-byte i minneslayout med en C-struktur). Kompilatorn kan omorganisera den hanterade strukturen på det sätt som den anser vara mest effektiv.
Pre-C++11 POD definition:
Ett aggregat är antingen en array eller en klass som inte har:
Ett aggregat kan initieras (som i C) med en lista av formen = {1, 2, 3};
Skalären heter:
(det vill säga en typ som inte är en klass, array eller referens)
En POD är antingen en skalär eller en uppsättning andra POD:er, eller en klass som är ett aggregat, och dessutom:
"Förutsägbar enhet i minnet" och "ingen kontrollkod" är liknande men olika typegenskaper. Till exempel kan datastrukturen STRRET[ 2] , som i Windows används för att skicka strängar från en minneshanterare till en annan, " lindas " i kontrollkoden, men den andra egenskapen, den förutsägbara enheten, finns kvar. Därför är begreppet PODs i C++11 uppdelat i tre.
En klass kallas "att ha en trivial kopia-konstruktor" om allt av följande är sant:
Den automatiskt genererade triviala kopia-konstruktorn är memmove().
Termerna "att ha en trivial standardkonstruktor/tilldelningsoperatör/flyttkonstruktör/flyttningsoperator" definieras på exakt samma sätt.
En klass kallas "att ha en trivial destruktor" om allt av följande är sant:
En sådan klass kräver inte förstörelse, och minnet som innehåller den kan deallokeras utan att rensas upp.
En klass sägs vara "trivialt kopierbar" om alla ovanstående specialmedlemsfunktioner är triviala (förutom standardkonstruktorn, som kan vara icke-trivial). Skalärer, såväl som arrayer av trivialt kopierbara objekt, är också trivialt kopierbara. Sådana typer kan kopieras via memcpy.
En klass kallas "trivial" om den är trivialt kopierbar och även har en trivial standardkonstruktor.
Med andra ord, en klass är trivial om den har trivial:
En klass är en standardenhetstyp om:
Låt oss förtydliga det sista villkoret: i språket kan det inte finnas två olika objekt av samma typ med samma adress, vilket innebär att storleken på en tom (utan icke-statiska fält) klass inte kan vara 0 (minst 1). Ett undantag görs dock för "del B i klass D : B" och dess storlek (om tom) kan vara strikt noll, vilket resulterar i ingen "utfyllnad" mellan början av D och dess första fält. Men samtidigt, om typen av det första fältet också är B, kan undantaget inte tillämpas, eftersom (B *) & d och & (d. fält1) pekar på olika objekt av samma typ, och därför " stoppning" behövs. Det sista villkoret från listan ovan betyder inget annat än "i klasserna för en standardanordning är en sådan packning förbjuden."
Sådana typer har en förutsägbar enhet i minnet (till exempel adressen för ett objekt som helhet är densamma som adressen för dess första fält, naturligtvis, efter reinterpret_cast till samma typ, till exempel to void *), kan de naturligtvis skickas till ett annat runtime-bibliotek och till andra språkprogrammering.
Då är POD en uppsättning andra PODs, eller en skalär, eller en trivial klass med en standardenhet, vars alla icke-statiska fält också är PODs.
För att arbeta med kompileringstidskonstanter och statisk initiering har C++11 ett mjukare koncept - en bokstavlig typ . Nämligen:
Sedan C++03 finns det en skillnad mellan T t; och Tt();, såväl som mellan nytt T och nytt T().
Versionen med tomma parenteser kallas "värdeinitiering", och utan dem kallas "standardinitiering".
Standardinitiering: om standardkonstruktorn är trivial, görs ingenting, skräp finns kvar i objektet. Om standardkonstruktorn inte är trivial, exekveras den.
Initiering efter värde: om det finns en explicit skriven standardkonstruktor, så exekveras den. Om inte (d.v.s. om standardkonstruktorn är trivial eller genereras automatiskt), så annulleras objektet först, och först därefter exekveras konstruktorn (om den är icke-trivial). Skalära typer sätts till noll när de initieras med ett värde.
Alla typer anses vara enkla datastrukturer förutom: