Me preguntaba cuál podría ser el tamaño de un objeto de una clase vacía . Seguramente no podría tener 0 bytes, ya que debería ser posible hacer referencia y señalarlo como cualquier otro objeto. Pero, ¿qué tan grande es un objeto así?
Usé este pequeño programa:
#include <iostream>
using namespace std;
class Empty {};
int main()
{
Empty e;
cerr << sizeof(e) << endl;
return 0;
}
¡El resultado que obtuve en los compiladores de Visual C ++ y Cygwin-g ++ fue de 1 byte ! Esto me sorprendió un poco, ya que esperaba que fuera del tamaño de la palabra de la máquina (32 bits o 4 bytes).
¿Alguien puede explicar por qué el tamaño de 1 byte? ¿Por qué no 4 bytes? ¿Esto depende del compilador o también de la máquina? Además, ¿alguien puede dar una razón más convincente de por qué un objeto de clase vacío no tendrá un tamaño de 0 bytes?
Respuestas:
Citando las Preguntas frecuentes sobre estilo y técnica de C ++ de Bjarne Stroustrup , la razón por la que el tamaño no es cero es "Para garantizar que las direcciones de dos objetos diferentes sean diferentes". Y el tamaño puede ser 1 porque la alineación no importa aquí, ya que no hay nada que realmente mirar.
fuente
new
; cuando se asigna el espacio, otra asignación debe tener una dirección diferente. Y así. No hay necesariamente ningún puntero involucrado en la clase vacía; puede haber punteros a las variables (o referencias, o asignaciones locales / de pila), pero no son de tamaño cero y no son necesariamente de tamaño de puntero.El estándar establece que todos los objetos derivados tienen sizeof ()> = 1:
fuente
Eso es realmente un detalle de implementación. Hace mucho tiempo, pensé que podría ser de cero bytes o mil bytes, que no tiene nada que ver con la especificación del lenguaje. Pero, después de mirar el estándar (sección 5.3.3),
sizeof
se define como devolver siempre uno o más, pase lo que pase.Esto es necesario, entre otras cosas, para permitirle manejar matrices de objetos y apuntadores a ellos. Si a sus elementos se les permitiera tener un tamaño cero,
&(array[0])
serían idénticos a&(array[42])
, lo que causará todo tipo de estragos en sus ciclos de procesamiento.La razón por la que puede no ser una palabra de máquina es que no hay elementos dentro de ella que realmente requieran que esté alineada en un límite de palabra (como un número entero). Por ejemplo, si coloca
char x; int y;
dentro de la clase, mi GCC lo registra en ocho bytes (ya que el segundo int debe estar alineado en esa implementación).fuente
Hay una excepción: matrices de longitud 0
fuente
c
,&c[M] == &c[N]
para cadaM
yN
(clang ++ 4.1).Aunque no es necesario asignar memoria para una clase vacía, pero para hacer objetos de clases vacías, el compilador asigna la memoria mínima que se puede asignar, que es 1 byte. De esta manera, el compilador puede distinguir dos objetos de la misma clase vacía de forma única y podrá asignar la dirección del objeto a un puntero del tipo de clase vacía.
fuente
Creo que podría ser útil vincular a una respuesta que explique esto también. Es acerca
boost::compressed_pair
de Logan Capaldo .fuente
Esto puede ayudarlo :-) http://bytes.com/topic/c/insights/660463-sizeof-empty-class-structure-1-a
fuente
La asignación de 1 byte para una clase vacía depende del compilador. Los compiladores deben asegurarse de que los objetos residan en diferentes ubicaciones de memoria y deben asignar un tamaño de memoria distinto de cero a un objeto. Escuche las notas sobre este tema aquí: http://listenvoice.com/listenVoiceNote.aspx?id=27
Aunque los compiladores asignan un tamaño distinto de cero a una clase vacía, también realizan optimizaciones cuando se derivan nuevas clases de clases vacías. Escuche sobre la optimización de la base vacía en las preguntas de la entrevista de programación en c ++ de ListenVoice.
fuente
la razón de la clase sin miembros de datos pero con un tamaño de 1 byte es que este * texto fuerte * debe almacenarse en la memoria para que una referencia o puntero pueda apuntar al objeto de esa clase
fuente
clase vacía: esa clase no tiene ningún contenido.
cualquier clase que no esté vacía estará representada por su contenido en la memoria.
ahora, ¿cómo se representará la clase vacía en la memoria? como no tiene contenido no hay forma de mostrar su existencia en la memoria, pero la clase está presente, es obligatorio mostrar su presencia en la memoria. Para mostrar la presencia de clase vacía en la memoria, se requiere 1 byte.
fuente
Creo que es así porque como 1 byte es la unidad de memoria más pequeña que se puede usar como marcador de posición, y no puede dar un tamaño cero, ya que no será posible crear una matriz de objetos.
y lo que dijiste "Esto me sorprendió un poco, ya que esperaba que fuera del tamaño de la palabra de la máquina (32 bits o 4 bytes)". será verdadero para la variable de referencia (palabras macine) de tipo vacío (), no el tamaño de la clase en sí (que es un tipo de datos abstracto),
fuente
Creo que esta pregunta es solo de interés teórico, pero no importa en la práctica.
Como ya han señalado otros, derivar de una clase vacía no hace ningún daño, ya que esto no consumirá memoria adicional para la parte de la clase base.
Además, si una clase está vacía (lo que significa que, en teoría, no necesita ninguna memoria por instancia, es decir, no tiene miembros de datos no estáticos o funciones de miembros virtuales), entonces todas sus funciones de miembros también pueden (y debería) definirse como estático. Por tanto, no es necesario crear una instancia de esta clase.
En pocas palabras: si se encuentra escribiendo una clase X vacía, haga que todas las funciones miembro sean estáticas. Entonces no necesitará crear objetos X, y las clases derivadas no se verán afectadas de ninguna manera.
fuente
Salida: Está bien tener diferentes direcciones
Devolver el tamaño 1 asegura que los dos objetos no tendrán la misma dirección.
fuente
Es distinto de cero para garantizar que los dos objetos diferentes tengan direcciones diferentes. Los diferentes objetos deben tener diferentes direcciones, por lo que el tamaño de una clase vacía es siempre de 1 byte.
fuente
Creo que si el tamaño de una clase vacía es cero, significa que no existe. Para que exista (clase), requiere tener al menos 1 byte, ya que este byte es la dirección de memoria / referencia.
fuente
Es debido a este puntero, aunque el puntero es (entero) de 4 bytes, pero se refiere a una ubicación de memoria (una Unidad) que es de 1 byte.
fuente