Frage

Wenn ich eine Klasse wie folgt

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

Und eine Struktur wie folgt

struct
{
   int x;
   int y;
} example_struct;

Ist die Struktur im Speicher des example_struct simmilar den in Example_Class

zum Beispiel, wenn ich die folgenden

struct example_struct foo_struct;
Example_Class foo_class = Example_Class();

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

wird foo_struct.x = 8 und foo_struct.y = 9 (dh: die gleichen Werte wie die x, y-Werte im foo_class)?

Der Grund, warum ich frage ist, ich habe eine C ++ Bibliothek (nicht will, es zu ändern), die ein Objekt mit C-Code teilt, und ich möchte eine Struktur verwenden, um das Objekt darzustellen aus der C ++ Bibliothek kommen. Ich bin daran interessiert sind nur in den Attributen des Objekts.

weiß, dass ich die ideale Situation rund um eine gemeinsame Struktur zwischen C und C ++ Code haben Example_class zu wickeln sein würde, aber es wird nicht einfach sein, die C ++ Bibliothek in Gebrauch zu ändern.

War es hilfreich?

Lösung

Der C ++ Standard Garantien , dass die Speicher-Layout eines C struct und einem C ++ class (oder struct - gleiche) wird identisch sein, vorausgesetzt, dass die C ++ class / struct die Kriterien des Seins paßt < strong> POD ( "Plain Old Data"). Also, was bedeutet POD das?

Eine Klasse oder Struktur ist POD, wenn:

  • Alle Daten sind Mitglieder der Öffentlichkeit und selbst POD oder Grundtypen (aber nicht Referenz oder Zeiger auf Elementtypen) oder Anordnungen solcher
  • Es hat keine benutzerdefinierten Konstrukteure, Zuweisungsoperatoren oder Destruktoren
  • Es hat keine virtuellen Funktionen
  • Es hat keine Basisklassen

über die einzigen „C ++ - Ismen“. Erlaubt sind nicht virtuelle Elementfunktionen, statische Elemente und Elementfunktionen

Da Ihre Klasse sowohl einen Konstruktor und Destruktor hat, es spricht formal nicht von POD-Typ, so dass die Garantie nicht gilt. (Obwohl, wie andere schon erwähnt haben, sind die zwei Layouts in der Praxis wahrscheinlich auf jedem Compiler identisch sein, dass Sie versuchen, so lange es keine virtuellen Funktionen).

Siehe Abschnitt [26.7] des C ++ FAQ Lite für weitere Details.

Andere Tipps

  

Ist die Struktur im Speicher des example_struct simmilar den in Example_Class

Das Verhalten nicht garantiert ist, und ist Compiler abhängig.

Having said that, die Antwort „ja, auf meinem Rechner“, vorausgesetzt, dass die Example_Class keine virtuelle Methode enthält (und erbt nicht von einer Basisklasse).

Im Fall, dass Sie beschreiben, ist die Antwort „wahrscheinlich ja“. Wenn jedoch die Klasse alle virtuellen Funktionen (einschließlich virtuellem destructor, die von einer Basisklasse geerbt werden könnte) hat, oder nutzt Mehrfachvererbung dann die Klasse Layout kann unterschiedlich sein.

, um hinzuzufügen, was andere Leute gesagt haben (zB: Compiler-spezifisch, wird wahrscheinlich funktionieren, solange Sie nicht virtuelle Funktionen haben):

Ich würde sehr empfehlen, eine statische assert (Kompilierung-Check), dass die sizeof (Example_class) == sizeof (example_struct), wenn Sie dies tun. Siehe BOOST_STATIC_ASSERT oder den gleichwertigen Compiler spezifische oder individuelle Konstruktion. Dies ist eine gute erste Linie der Verteidigung, wenn jemand (oder etwas, wie ein Compiler ändern) die Klasse ändert das Spiel ungültig zu machen. Wenn Sie zusätzliche Überprüfung möchten, können Sie auch prüfen, Laufzeit, dass die Offsets an die Mitglieder die gleichen sind, die (zusammen mit der statischen Größe assert) wird Korrektheit garantieren.

In den frühen Tagen der C ++ Compiler es Beispiele waren, als Compiler erste Änderungen struct Schlüsselwörter mit Klasse und dann kompiliert. So viel über Ähnlichkeiten.

Die Unterschiede kommen aus Klassenvererbung und vor allem virtuellen Funktionen. Wenn Klasse virtuelle Funktionen enthält, dann muss es einen Zeiger muß Descriptor am Anfang seines Layouts eingeben. Auch, wenn die Klasse B von Klasse A erbt, dann Layout-Klasse A ist an erster Stelle, gefolgt von der Klasse B eigenen Layout.

So ist die genaue Antwort auf Ihre Frage nur eine Klasseninstanz zu einer Strukturinstanz Gießen ist: abhängig von der Klasse Inhalt. Für bestimmte Klasse, die Methoden (Konstruktor und nicht-virtuellen destructor) hat, wird das Layout wahrscheinlich das gleiche sein wird. Sollte der Destruktor virtuell deklariert werden, würde das Layout definitiv anders geworden zwischen Struktur und Klasse.

Hier ist ein Artikel, der zeigt, dass es nicht viel gebraucht wird, ist aus C-Strukturen zu C ++ Klassen zu tun zu Schritt: Lektion 1 - von der Struktur zur Klasse

Und hier ist der Artikel, der erklärt, wie virtuelle Funktionen Tabelle Klassen eingeführt, die virtuelle Funktionen haben: Lektion 4 - Polymorphismus

Klassen & structs in C ++ die äquivalent sind, mit der Ausnahme, dass alle Mitglieder einer Struktur öffentlich sind standardmäßig (Klasse Mitglieder sind standardmäßig privat). Dadurch wird sichergestellt, dass in einem C ++ Compiler Legacy-C-Code kompiliert wird wie erwartet.

Es gibt nichts hindert Sie daran, mit allen die Phantasie C ++ Funktionen in einer Struktur:

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

    /// etc etc etc
};

Warum nicht explizit die Mitglieder der Klasse zuweisen, um die Struktur der, wenn Sie die Daten C übergeben möchten? Auf diese Weise wissen Sie Ihren Code überall funktionieren.

Sie wahrscheinlich ableiten nur die Klasse aus der Struktur, entweder öffentlich oder privat. Dann Gießen es richtig in der C ++ Code zu beheben wäre.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top