Je me demandais quelle pouvait être la taille d'un objet d'une classe vide . Il ne peut certainement pas être de 0 octet car il devrait être possible de le référencer et de le pointer comme n'importe quel autre objet. Mais quelle est la taille d'un tel objet?
J'ai utilisé ce petit programme:
#include <iostream>
using namespace std;
class Empty {};
int main()
{
Empty e;
cerr << sizeof(e) << endl;
return 0;
}
La sortie que j'ai obtenue sur les compilateurs Visual C ++ et Cygwin-g ++ était de 1 octet ! C'était un peu surprenant pour moi car je m'attendais à ce qu'il soit de la taille du mot machine (32 bits ou 4 octets).
Quelqu'un peut-il expliquer pourquoi la taille de 1 octet? Pourquoi pas 4 octets? Cela dépend-il aussi du compilateur ou de la machine? En outre, quelqu'un peut-il donner une raison plus convaincante pour laquelle un objet de classe vide ne sera pas de taille 0 octet?
Réponses:
Citant la FAQ sur le style et la technique C ++ de Bjarne Stroustrup , la raison pour laquelle la taille est différente de zéro est «Pour s'assurer que les adresses de deux objets différents seront différentes». Et la taille peut être 1 car l'alignement n'a pas d'importance ici, car il n'y a rien à regarder.
la source
new
; lorsque l'espace est alloué, une autre allocation doit avoir une adresse différente. Etc. Il n'y a pas nécessairement de pointeur impliqué dans la classe vide; il peut y avoir des pointeurs vers les variables (ou des références, ou des allocations locales / de pile), mais ils ne sont pas de taille nulle et ils ne sont pas nécessairement de taille de pointeur.La norme stipule que la plupart des objets dérivés ont sizeof ()> = 1:
la source
C'est vraiment un détail de mise en œuvre. Il y a longtemps, je pensais que cela pouvait être zéro octet ou mille octets, que cela n'avait aucune incidence sur la spécification du langage. Mais, après avoir regardé la norme (section 5.3.3),
sizeof
est définie comme renvoyant toujours un ou plus, quoi qu'il arrive.Ceci est nécessaire, entre autres, pour vous permettre de gérer des tableaux d'objets et des pointeurs vers eux. Si vos éléments étaient autorisés à être de taille nulle, alors
&(array[0])
ils seraient identiques à&(array[42])
, ce qui causera toutes sortes de ravages dans vos boucles de traitement.La raison pour laquelle ce n'est peut-être pas un mot machine est qu'il n'y a pas d'éléments en son sein qui nécessitent en fait qu'il soit aligné sur une limite de mot (comme un entier). Par exemple, si vous placez
char x; int y;
à l'intérieur de la classe, mon GCC l'horloge à huit octets (puisque le deuxième int doit être aligné dans cette implémentation).la source
Il y a une exception: les tableaux de longueur 0
la source
c
,&c[M] == &c[N]
pour tousM
etN
(clang ++ 4.1).Même s'il n'est pas nécessaire d'affecter de la mémoire pour une classe vide, mais afin de créer des objets de classes vides, le compilateur affecte la mémoire minimale pouvant être affectée, qui est de 1 octet. De cette façon, le compilateur peut distinguer deux objets de la même classe vide de manière unique et pourra attribuer l'adresse de l'objet à un pointeur du type de classe vide.
la source
Je pense qu'il pourrait être utile de faire un lien vers une réponse expliquant ce bien aussi. Il est à propos
boost::compressed_pair
de Logan Capaldo .la source
Cela peut vous aider :-) http://bytes.com/topic/c/insights/660463-sizeof-empty-class-structure-1-a
la source
L'allocation de 1 octet pour une classe vide dépend du compilateur. Les compilateurs doivent s'assurer que les objets résident dans des emplacements de mémoire différents et ils doivent allouer une taille de mémoire non nulle à un objet. Écoutez les notes sur ce sujet ici: http://listenvoice.com/listenVoiceNote.aspx?id=27
Même si les compilateurs allouent une taille non nulle à une classe vide, ils effectuent également des optimisations lorsque de nouvelles classes sont dérivées de classes vides. Écoutez l'optimisation de la base vide sur les questions d'entrevue de programmation C ++ de ListenVoice.
la source
la raison pour une classe sans données membres mais ayant une taille de 1 octet est que ce * texte fort * doit être stocké en mémoire afin qu'une référence ou un pointeur puisse pointer vers l'objet de cette classe
la source
classe vide - cette classe ne contient aucun contenu.
toute classe qui n'est pas vide sera représentée par son contenu en mémoire.
maintenant comment la classe vide sera-t-elle représentée en mémoire? comme il n'a aucun contenu aucun moyen de montrer son existence en mémoire, mais la classe est présente, il est obligatoire de montrer sa présence en mémoire. Pour afficher la présence de classe vide dans la mémoire, 1 octet est requis.
la source
Je pense que c'est le cas car 1 octet est la plus petite unité de mémoire qui peut être utilisée comme espace réservé, et elle ne peut pas donner une taille nulle car il ne sera pas possible de créer un tableau d'objets.
et le truc que vous avez dit "Cela m'a un peu surpris car je m'attendais à ce qu'il soit de la taille du mot machine (32 bits ou 4 octets)." sera vrai pour la variable de référence (mots macine) de type empty (), pas pour la taille de la classe elle-même (qui est du type de données abstrait),
la source
Je pense que cette question n'a qu'un intérêt théorique mais n'a pas d'importance en pratique.
Comme déjà souligné par d'autres, dériver d'une classe vide ne fait aucun mal, car cela ne consommera pas de mémoire supplémentaire pour la partie de la classe de base.
De plus, si une classe est vide (ce qui signifie qu'elle - théoriquement - n'a pas besoin de mémoire par instance, c'est-à-dire qu'elle n'a pas de membres de données non statiques ou de fonctions membres virtuelles) alors toutes ses fonctions membres peuvent tout aussi bien (et devrait) être défini comme statique. Il n'est donc pas nécessaire de créer une instance de cette classe.
Bottom line: Si vous vous retrouvez à écrire une classe X vide, alors rendez toutes les fonctions membres statiques. Vous n'aurez alors plus besoin de créer des objets X et les classes dérivées ne seront en aucun cas affectées.
la source
Sortie: Ok, c'est bien d'avoir différentes adresses
Le renvoi de la taille 1 garantit que les deux objets n'auront pas la même adresse.
la source
Il est différent de zéro pour garantir que les deux objets différents auront des adresses différentes. Différents objets doivent avoir des adresses différentes, donc la taille d'une classe vide est toujours de 1 octet.
la source
Je pense que si la taille d'une classe vide est nulle, cela signifie qu'elle n'existe pas. Pour qu'elle (classe) existe, elle nécessite d'avoir au moins 1 octet, puisque cet octet est l'adresse mémoire / référence.
la source
C'est à cause de ce pointeur, bien que le pointeur soit (entier) de 4 octets mais il se réfère à un emplacement de mémoire unique (une unité) qui est de 1 octet.
la source