6
votes

Ordre de stockage dans une structure / objet

Considérez ces deux cas:

class CustomType
{
   public:
       dataType1 member1;
       dataType2 member2;

       retrunType1 memberFunction1();

   private:
       dataType3 member3;
       dataType4 member4;

       retrunType2 memberFunction2();
};

customType object;
// Assume member1, member2, member3 and member4 were initialized to some valid values.

customType *pointerToAnObject = &object ;
dataType1 firstMemberInTheObject = (dataType1) (*pointerToAnObject);


6 commentaires

Certainement pas si la classe est polymorphe. Mais je ne suis pas sûr des détails techniques de quand c'est exactement à faire.


Dans C ++, les classes et les structures sont fondamentalement les mêmes en plus du mot clé. Le dataorder est tel que vous descritez, mais si vous voulez être sûr à 100%, vous pouvez utiliser l'héritage, si vous avez juste besoin d'accéder au premier objet. BTW Pourquoi ne créez-vous pas des pointeurs directs vers les membres, vous pouvez faire quelque chose comme * (ClassInstanceCoinger-> Memberpointer) (environ a été un certain temps) pour accéder aux données, en échangeant le pointeur d'instance que vous avez peut accéder aux données dans différentes instances.


Je ne pense pas que ce soit une chose généralement sûre à faire en C ++: vous devez prendre en compte la base (dérivée). L'ordre des variables de membre est garanti pour correspondre à la source. Il n'est pas très différent pour les classes C et C ++: C ++ peuvent avoir des classes parent et une table de méthodes virtuelles, que c n'a pas. Cela rend le résultat de "FirstMemberinObject" un peu plus difficile à lire de la source. En outre, l'alignement des champs peut ajouter du rembourrage avant le premier champ.


@ted: & instance.member, qui est une chose complètement sûre à faire


@ Fork0 & instance.member Pour configurer le pointeur, Yezx j'ai oublié de mettre cela. Mais je pense que je peux racoler quelque chose comme Auto p = & Classe :: membre et Auto Inst = & Class () Pour être utilisé membre de l'Ass Membre et pointeur d'instance dans le code que j'ai mentionné ci-dessus . Dans votre cas, il semble que vous obteniez déjà un pointeur d'objet lié que je pense différent légèrement du résultat souhaité.


@ted: Ce & classe :: membre ne fonctionne que pour des éléments statiques d'une classe. Ce serait des variables et des méthodes statiques (vous pouvez obtenir une adresse d'une méthode par & opérateur). L'autre construction est en fait une erreur: vous obtenez une adresse à un objet temporaire. Peut toujours avoir ses utilisations cependant: comme un argument à une fonction: Func (& classe (classe ()) . L'utilisation d'une référence dans cet argument le rendra plus court.


4 Réponses :


0
votes

Typiquement dans les membres de la structure C sont stockés dans l'ordre qu'ils sont déclarés. Cependant, les éléments doivent être alignés correctement. Wikipedia a un bon exemple de Comment cela fonctionne .

Je vais ré-itération ici : P>

Si vous avez la structure suivante P>

struct MixedData
{
    char Data1;
    short Data2;
    int Data3;
    char Data4;
};


2 commentaires

La première déclaration est fausse en cas d'entrelacement des champs protégés par le secteur privé.


C n'a pas de tel mécanisme. Désolé, j'ai peut-être dû dire typiquement en C. Je n'ai pas le pouvoir de dire quoi que ce soit à propos de C ++: p



1
votes

Ce n'est pas toujours sûr de le faire. Si les classes ont des méthodes virtuelles , il n'est certainement pas. Les membres de données sont garantis dans le même ordre pour le même chunk de niveau d'accès, mais ces groupes peuvent être réorganisés.

Pour être sûr avec ce type de moulage, vous devez fournir un constructeur de conversion ou un opérateur de distribution et ne pas compter sur les détails de la mise en œuvre.


0 commentaires

6
votes

9.0.7

Une classe de mise en page standard est une classe qui: - n'a pas de données non statiques membres de la classe de type non standard de type (ou une matrice de tels types) ou Référence, - n'a aucune fonction virtuelle (10.3) et aucune base virtuelle classes (10.1), - a le même contrôle d'accès (clause 11) pour tous Membres de données non statiques, - N'a pas de classes de base non normalisées, - soit n'a pas de membres de données non statiques dans la classe la plus dérivée et à la plupart des classes de base avec des membres de données non statiques, ou n'ont pas de base classes avec des membres de données non statiques et - n'a pas de classes de base de la même type que le premier élément de données non statique.108

9.2.14

Membres de données non statiques d'une classe (non syndicale) avec le même accès contrôle (clause 11) sont alloués de manière à ce que les membres ultérieurs soient plus élevés adresses dans un objet de classe. L'ordre d'attribution de non-statique Les membres de données avec différents contrôles d'accès sont non spécifiés (11). Les exigences d'alignement de la mise en œuvre peuvent provoquer deux membres adjacents ne pas être alloué immédiatement après l'autre; alors pourrait Conditions requises pour la gestion des fonctions virtuelles (10.3) et Classes de base virtuelles (10.1).

9.2.20

Un pointeur sur un objet de structure de mise en page standard, convenablement converti en utilisant une réinterpret_cast, pointe vers son membre initial (ou si ce membre est Un champ de bits, puis à l'unité dans laquelle il réside) et vice versa. [ Remarque: il pourrait donc y avoir un rembourrage sans nom dans un objet de structure standard, mais pas à son début, si nécessaire pour atteindre l'alignement approprié. - Note de fin]


0 commentaires

7
votes

C99 et C ++ diffèrent un peu à ce sujet.

La norme C99 garantit que les champs d'une structure seront définis dans la mémoire dans l'ordre de leur déclaration et que les champs de deux structures identiques auront les mêmes compensations. Voir Cette question pour les sections pertinentes de la norme C99. Pour résumer: le décalage du premier champ est spécifié pour être zéro, mais les compensations suivantes ne sont pas spécifiées par la norme. Ceci permet de permettre aux compilateurs C d'ajuster les compensations de chaque champ afin que le champ satisfasse toutes les exigences d'alignement de la mémoire de l'architecture. Comme il s'agit de la mise en œuvre dépendante de la mise en œuvre, c fournit un moyen standard de déterminer le décalage de chaque champ à l'aide du offset de code> macro. p>

C ++ offre cette garantie uniquement pour Données anciennes simples (POD) . C ++ classes qui ne sont pas des données anciennes simples ne peuvent pas être traitées comme ceci. La norme donne au compilateur C ++ un peu de liberté dans la manière dont il organise une classe lorsque la classe utilise plusieurs héritages, possède des champs ou des membres non publics, ou contient des membres virtuels. P>

Qu'est-ce que cela signifie pour vos exemples : P>

dataType1 firstMemberInTheObject = (dataType1) (*pointerToAnObject);


0 commentaires