Oppbygging av et C ++ Object minne Vs en Struct

stemmer
42

Hvis jeg har en klasse som følger

   class Example_Class 
   {
       private:
         int x; 
         int y; 
       public: 
         Example_Class() 
         { 
             x = 8;
             y = 9;
         }
       ~Example_Class() 
       { } 
   };

Og en struct som følger

struct
{
   int x;
   int y;
} example_struct;

Er strukturen til minne om example_structsimmilar til at iExample_Class

for eksempel hvis jeg gjør følgende

struct example_struct foo_struct;
Example_Class foo_class = Example_Class();

memcpy(&foo_struct, &foo_class, sizeof(foo_struct));

vil foo_struct.x = 8og foo_struct.y = 9(dvs: de samme verdiene som x, y verdier i foo_class)?

Grunnen til at jeg spør er at jeg har en C ++ bibliotek (ønsker ikke å endre det) som deler et objekt med C-kode, og jeg ønsker å bruke en struct å representere objektet kommer fra C ++ bibliotek. Jeg er bare interessert i attributtene til objektet.

Jeg vet den ideelle situasjonen ville være å ha Example_class vikle arround en felles struktur mellom C og C ++ kode, men det er ikke til å bli lett å endre C ++ bibliotek i bruk.

Publisert på 08/01/2009 klokken 00:59
kilden bruker
På andre språk...                            


8 svar

stemmer
60

C ++ standarden garanterer at minne oppsett av en C structog C ++ class(eller struct- samme) vil være identiske, forutsatt at C ++ class/ structoppfyller kriteriene for å bli POD ( "Plain Old data"). Så hva POD mener?

En klasse eller struct er POD dersom:

  • Alle data medlemmer er offentlig og selv POD eller grunnleggende typer (men ikke referere eller peker til medlem typer), eller matriser med slikt
  • Det har ingen brukerdefinerte konstruktører, oppdrag operatører eller destructors
  • Det har ingen virtuelle funksjoner
  • Det har ingen grunnklasser

Om den eneste "C ++ - ismer" tillatt ikke-virtuelle medlem funksjoner, statiske medlemmer og medlemsfunksjoner.

Siden klassen din har både en konstruktør og destructor, er det formelt sett ikke fra POD type, slik at garantien ikke holder. (Selv om, som andre har nevnt, i praksis de to oppsettene er sannsynlig å være identisk på alle kompilator som du prøver, så lenge det ikke er noen virtuelle funksjoner).

Se avsnitt [26.7] av C ++ FAQ Lite for mer informasjon.

Svarte 08/01/2009 kl. 05:30
kilden bruker

stemmer
10

Er strukturen i minnet til example_struct simmilar som i Example_Class

Oppførselen er ikke garantert, og er kompilatoren avhengig.

Når det er sagt, er svaret "ja, på min maskin", forutsatt at Example_Class inneholder virtuell metode (og ikke arver fra en base klasse).

Svarte 08/01/2009 kl. 01:02
kilden bruker

stemmer
7

I tilfelle du beskriver, er svaret "sannsynligvis ja". Imidlertid, hvis den klasse har noen virtuelle funksjoner (inkludert virtuelle destructor, som kan være arvet fra en basisklasse), eller benytter multippel arv og klassen utformingen kan være forskjellig.

Svarte 08/01/2009 kl. 01:02
kilden bruker

stemmer
3

For å legge til hva andre har sagt (f.eks: kompilator-spesifikke, vil trolig fungere så lenge du ikke har virtuelle funksjoner):

Jeg vil foreslå en statisk hevde (kompilere-tid sjekk) at sizeof (Example_class) == sizeof (example_struct) hvis du gjør dette. Se BOOST_STATIC_ASSERT, eller tilsvarende kompilator-spesifikke eller tilpasset konstruksjon. Dette er en god første-linje av forsvar hvis noen (eller noe, for eksempel en kompilator endring) modifiserer klassen å ugyldig kampen. Hvis du vil ha ekstra kontroll, kan du også runtime sjekke at forskyvninger til medlemmene er de samme, som (sammen med den statiske størrelse hevde) vil garantere korrekthet.

Svarte 08/01/2009 kl. 01:49
kilden bruker

stemmer
0

I de tidlige dagene av C ++ kompilatorer var det eksempler når kompilatoren først endrer struct søkeord med klasse og deretter kompilerer. Så mye om likheter.

Forskjeller kommer fra klassen arv og, spesielt, virtuelle funksjoner. Hvis klassen inneholder virtuelle funksjoner, så det må ha en peker til å skrive descriptor i begynnelsen av oppsettet. Også, hvis klasse B arver fra klassen A, deretter klasse A layout kommer først, etterfulgt av klasse B egen layout.

Så nøyaktig svar på spørsmålet ditt om bare å kaste en klasse eksempel til en struktur eksempel er: avhenger av klassen innhold. For spesielle klasse som har metoder (konstruktøren og ikke-virtuelle destructor), er oppsettet sannsynligvis kommer til å være den samme. Skulle destructor bli erklært virtuelle, ville oppsettet definitivt blitt annerledes mellom struktur og klasse.

Her er en artikkel som viser at det ikke er mye som trengs for å gjøre for å gå fra C strukturer til C ++ klasser: Leksjon 1 - Fra struktur til klasse

Og her er artikkelen som forklarer hvordan virtuelle funksjoner tabellen er introdusert til klasser som har virtuelle funksjoner: Leksjon 4 - Polymorphism

Svarte 22/12/2013 kl. 09:06
kilden bruker

stemmer
0

Hvorfor ikke eksplisitt tildele klassens medlemmer til struct er når du ønsker å sende data til C? På den måten vet du koden vil fungere hvor som helst.

Svarte 08/01/2009 kl. 05:43
kilden bruker

stemmer
0

Kurs og structs i C ++ er det samme, bortsett fra at alle medlemmer av en struct er offentlige som standard (klassemedlemmene er private som standard). Dette sikrer at kompilering arven C-kode i en C ++ kompilatoren vil fungere som forventet.

Det er ingenting som hindrer deg fra å bruke alle de fancy C ++ funksjoner i en struct:

struct ReallyAClass
{
    ReallyAClass();
    virtual !ReallAClass();

    /// etc etc etc
};
Svarte 08/01/2009 kl. 01:52
kilden bruker

stemmer
-2

Du har sannsynligvis bare utlede klasse fra struct, enten offentlig eller privat. Deretter kaster det ville løse riktig i C ++ kode.

Svarte 08/01/2009 kl. 06:39
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more