Enkel datastruktur

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 20 november 2013; kontroller kräver 58 redigeringar .

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.

Fördelar med enkla datastrukturer

Enkla datastrukturer har två funktioner.

Förutsägbar enhet i minnet

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.

Ingen kontrollkod

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:

  1. Statisk initiering. Istället för att anropa konstruktorn gömd för programmeraren när programmet startas, kan POD:er sättas ihop medan programmet kompileras.
  2. Trivial kopiering (inklusive kopieringsarrayer) med funktioner som memcpy.
  3. Återigen är detta viktigt för kommunikation mellan program: trots allt ska minneshanteraren inte hantera minne som inte tillhör honom.
  4. Endast enkla typer kan finnas i union(i Pascal, respektive record/case).
  5. Funktioner med biverkningar (som systemfunktioner som påverkar resultatet av ett efterföljande samtal GetLastError[1] ) är dåligt kompatibla med automatiskt hanterade typer.

Språk där alla typer är enkla

I C++

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:

I C++11

"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:

PODs och "default" och "value" initiering

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.

Embarcadero Delphi

Alla typer anses vara enkla datastrukturer förutom:

Anteckningar

  1. GetLastError Arkiverad 6 december 2013 på Wayback MachineMSDN
  2. STRRET-struktur (Windows) . Hämtad 6 april 2013. Arkiverad från originalet 18 april 2013.

Se även