2010-03-02 9 views
55

Duplicar posibles:
C++: What is the size of an object of an empty class?¿Por qué el tamaño de una clase vacía en C++ no es cero?

¿Por qué la siguiente salida 1?

#include <iostream> 

class Test 
{ 
}; 

int main() 
{ 
    std::cout << sizeof(Test); 
    return 0; 
} 
+4

Hay un miembro de marcador ficticio cuyo tamaño es de un byte. Dado que para una matriz de Prueba [10], cada objeto debe tener una dirección única. – legends2k

+4

Sin embargo, una optimización interesante es la 'Optimización de Base Vacía', lo que significa que si heredas de una clase base vacía (sin atributos, sin métodos virtuales), entonces tu tamaño de clase no crecerá. Hay una serie de (otras) condiciones, pero explica por qué hereda de forma privada los predicados en algunas situaciones. –

+0

[pregunta similar 1] (http://stackoverflow.com/questions/1626446) y [pregunta similar 2] (http://stackoverflow.com/questions/621616/). – Lazer

Respuesta

86

La norma no permite objetos (y clases de los mismos) de tamaño 0, ya que ello hacer posible que los dos objetos distintos tengan la misma dirección de memoria. Es por eso que incluso las clases vacías deben tener un tamaño de (al menos) 1.

+2

Hm ... ¿pero no debería el enlazador ser capaz de encargarse de eso sin importar qué tamaño de() devuelva? ¿No es esto más como un efecto secundario? Entiendo lo que dices, pero ¿no es perfectamente posible devolver 0 para sizeof (prueba)? Pero si el estándar así lo dice, lo dice. En realidad, es bueno que una vez sea explícito en lugar de intencionalmente vago sobre un tema. –

+12

@Amigable, entonces, ¿qué tendría 'Test a [10];' como tamaño? Y 'sizeof a/sizeof * a' se dividiría por 0. Y' for (Test * i = a; i! = A + 10; i ++) f (i); 'tampoco funcionaría. Creo que causaría muchos problemas, ya que necesita una gran cantidad de casos especiales en los compiladores * y * en el código de usuario. –

+0

@Johannes, tan cierto. No pensé en eso. –

27

Para asegurar que las direcciones de dos objetos diferentes sean diferentes. Por la misma razón, "nuevo" siempre devuelve punteros a objetos distintos.

Ver Stroustrup para la respuesta completa.

+1

Ir al enlace de la página directa –

20

El estándar C++ garantiza que el tamaño de cualquier clase es al menos uno. El estándar de C++ establece que ningún objeto tendrá la misma dirección de memoria que otro objeto. Hay varias buenas razones para esto.

  1. Para garantizar que new siempre devolverá un puntero a una dirección de memoria distinta.

  2. Para evitar algunas divisiones por cero. Por ejemplo, los aritméticos de punteros (muchos de los cuales los hace automáticamente el compilador) implican dividir por sizeof(T).

Nota sin embargo, que esto no significa que una clase base vacía añadirá 1 al tamaño de una clase derivada:

struct Empty { }; 

struct Optimized : public Empty { 
    char c; 
}; 

// sizeof(Optimized) == 1 with g++ 4.0.1 

Bjarne Stroustrup talks about this también.

+2

¿Qué aritmética de puntero incluye _dividing_ por 'sizeof (T)'? No puedo pensar en un solo ejemplo. Plase agrega al menos un ejemplo. – MSalters

+4

@MSalters: iteración sobre matrices de elementos del tipo T. – wilhelmtell

+1

@MSalters: resta de dos punteros devuelve el número de elementos, no el número de bytes, en el medio. –

3

Lo que dijeron Maurits y Péter.

Es interesante señalar en este contexto que los compiladores pueden hacer la optimización de la clase base vacía (EBCO):

#include <iostream> 
struct Foo {}; 
struct Bar : Foo {}; 
int main() { 
    std::cout << sizeof(Foo) << ',' << sizeof(Bar) << std::endl;   
} 

Esto probablemente se imprimirá "1,1" si se compila y ejecuta. Ver también Vandevoorde/Josuttis 16.2 en EBCO.

9

Clase sin ningún miembro de datos y función de miembro, este tipo de clase se conoce como clase vacía. El tamaño del objeto de la clase vacía es siempre de 1 byte.

Cuando creamos el objeto de cualquier clase en ese momento, el objeto siempre obtiene 3 características, es decir

  1. Estado
  2. Comportamiento
  3. Identidad

Cuando creamos objeto de la clase vacía en ese estado el tiempo de ese objeto no es nada. El comportamiento de ese objeto tampoco es nada, pero el compilador asigna una dirección única a ese objeto. La memoria en la computadora siempre se organiza en forma de bytes y la memoria mínima disponible en la ubicación de la dirección del objeto es de 1 byte. Es por eso que el tamaño del objeto de la clase vacía es de 1 byte.

+0

si alguien quisiera saber tres características de un objeto, es decir 1) Estado 2) Comportamiento 3) Identidad luego pregúntame – Shantanu

Cuestiones relacionadas