56 votes

Structure d'un objet C ++ en mémoire contre une structure

Si j'ai une classe comme suit

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

Et une structure comme suit

struct
{
   int x;
   int y;
} example_struct;

Est la structure dans la mémoire de l' example_struct simmilar pour que, en Example_Class

par exemple, si je ne les suivants

struct example_struct foo_struct;
Example_Class foo_class = Example_Class();

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

va foo_struct.x = 8 et foo_struct.y = 9 (c'est à dire: les mêmes valeurs que les valeurs x,y dans le foo_class) ?

La raison pour laquelle je demande c'est que j'ai une bibliothèque C++ (ne veux pas le changer) c'est le partage d'un objet avec du code C et je veux utiliser une structure pour représenter l'objet en provenance de la bibliothèque C++. Je suis seulement intéressé par les attributs de l'objet.

Je sais que la situation idéale serait d'avoir Example_class enrouler autour d'une structure commune entre le code C et C++, mais il ne va pas être facile de changer le C++ de la bibliothèque en cours d'utilisation.

75voto

j_random_hacker Points 28473

La norme C++ garantit que la mémoire les mises en page d'un C struct et un C++ class (ou struct -- même chose) sera identique, à condition que le C++ class/struct correspond aux critères de POD (Plain Old Données"). Donc, ce n'est POD veux dire?

Une classe ou structure est POD si:

  • Tous les membres de données sont publiques et se POD ou types fondamentaux (mais pas de référence ou pointeur-à-types de membres), ou des tableaux de tels
  • Il n'a pas défini par l'utilisateur des constructeurs, des opérateurs d'affectation ou des destructeurs
  • Il n'a pas de fonctions virtuelles
  • Il n'a pas de classes de base

Sur le seul "C++-ismes" autorisées sont non-membre virtuel fonctions membres statiques et les fonctions de membres.

Depuis votre classe a un constructeur et un destructeur, il est formellement parlant, pas de type POD, de sorte que la garantie ne tient pas. (Bien que, comme d'autres l'ont mentionné, dans la pratique, les deux dispositions sont susceptibles d'être identique sur n'importe quel compilateur que vous essayez, tant qu'il n'y a pas de fonctions virtuelles).

Voir la section [de 26,7] du C++ FAQ Lite pour plus de détails.

10voto

ChrisW Points 37322

La structure en mémoire de example_struct est-elle identique à celle de Example_Class?

Le comportement n'est pas garanti et dépend du compilateur.

Cela dit, la réponse est "oui, sur ma machine", à condition que Example_Class ne contienne aucune méthode virtuelle (et n'hérite pas d'une classe de base).

7voto

Greg Hewgill Points 356191

Dans le cas que vous décrivez, la réponse est "probablement oui". Cependant, si la classe a des fonctions virtuelles (y compris un destructeur virtuel, qui pourrait être hérité d'une classe de base), ou utilise un héritage multiple, la structure de la classe peut être différente.

3voto

Nick Points 5293

Pour ajouter à ce que d'autres personnes l'ont dit (par exemple: un compilateur spécifique, sera probablement travailler aussi longtemps que vous n'avez pas de fonctions virtuelles):

Je vous suggère fortement d'une statique assert (au moment de la compilation à vérifier) que la sizeof(Example_class) == sizeof(example_struct) si vous faites cela. Voir BOOST_STATIC_ASSERT, ou l'équivalent compilateur spécifique ou de construction sur mesure. C'est une bonne première ligne de défense, si quelqu'un (ou quelque chose, comme un compilateur changement) modifie la classe d'invalider le match. Si vous souhaitez plus de la vérification, vous pouvez aussi le moment de l'exécution que les décalages pour les membres sont les mêmes, le (avec la statique de la taille de l'affirmer) permet de garantir l'exactitude.

0voto

Mike Thompson Points 4178

Les classes et les structures en C ++ sont équivalentes, sauf que tous les membres d'une structure sont publics par défaut (les membres de classe sont privés par défaut). Cela garantit que la compilation du code C hérité dans un compilateur C ++ fonctionnera comme prévu.

Rien ne vous empêche d'utiliser toutes les fonctionnalités C ++ sophistiquées d'une structure:

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

    /// etc etc etc
};
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X