sintaxis - c++ sizeof() de una clase con funciones
sizeof(int) (7)
P: ¿Las funciones virtuales ocupan espacio por objeto y, por lo tanto, aumentan el tamaño de un objeto?
R: No. Mientras más funciones virtuales, más grande es vtable. Cuantas más subclases, más vtables. Si una clase no tiene funciones virtuales, entonces no hay necesidad de un puntero vtable o vtable (por objeto).
Pero nada de esto afecta al "tamaño de". Las funciones en sí toman una cantidad fija de espacio, independientemente.
Tengo una pregunta de C ++. Escribí la siguiente clase:
class c
{
int f(int x, int y){ return x; }
};
El tamaño de () de la clase c devuelve "1". Realmente no entiendo por qué devuelve 1.
Intentando entender mejor lo que está pasando, agregué otra función:
class c
{
int f(int x, int y){ return x; }
int g(int x, int y){ return x; }
};
Ahora lo siguiente realmente me tiene confundido! sizeof (c) sigue siendo 1 (!?!?!?!). Así que supongo que las funciones no cambian el tamaño de la clase, pero ¿por qué? ¿Y por qué el tamaño es 1? ¿Y es específico del compilador?
¡Gracias! :-)
sizeof (char) == 1 siempre, porque un char es un byte y sizeof devuelve un número de bytes. (Sin embargo, un byte no es necesariamente exactamente ocho bits).
Totalmente cierto. De ahí el término "octeto" (para distinguir algo que es exactamente 8 bits del término más comúnmente usado "byte").
Para más información, mira IEEE 1541:
1 significa 1 byte. Y la resonancia es que los métodos no se almacenan dentro de un objeto. Son usados por objetos, pero no almacenados en ellos. Sólo los miembros de la clase se almacenan en objetos. Intente agregar un miembro int
simple o algo y ver qué sucede.
Debido a que su clase es una "variable de referencia" y, según MSDN: "El operador sizeof nunca da 0, incluso para una clase vacía".
EJEMPLO:
class c
{
public:
int f(int x, int y){ return x; }
int g(int x, int y){ return x; }
}; struct s
{
int f;
int g;
}; int
main (int argc, char *argv[])
{
c objc;
s objs;
printf ("sizeof (c)= %d, sizeof (objc)= %d, sizeof (class c)= %d.../n",
sizeof (c), sizeof (objc), sizeof (class c));
printf ("sizeof (s)= %d, sizeof (objs)= %d, sizeof (struct s)= %d.../n",
sizeof (s), sizeof (objs), sizeof (struct s));
return 0;
}#include <stdio.h>
RESULTADO:
sizeof (c)= 1, sizeof (objc)= 1, sizeof (class c)= 1... sizeof (s)= 8, sizeof (objs)= 8, sizeof (struct s)= 8...
Tenga en cuenta, también, la diferencia entre "struct" y "class".
Aquí hay más información:
La clase no contiene miembros de datos, por lo que está vacía. El estándar exige que cada clase tenga al menos el tamaño 1, así que eso es lo que obtienes. (Las funciones de los miembros no están físicamente "dentro" de una clase, en realidad son solo funciones gratuitas con un argumento oculto y un espacio de nombres y control de acceso).
Las funciones de los miembros son, esencialmente, lo mismo que las funciones normales, solo consiguen un parámetro oculto. Por lo tanto, no es necesario que cada instancia de un tipo dado lleve consigo copias de sus funciones miembro; el compilador simplemente realiza un seguimiento de las funciones normales y proporciona un parámetro adecuado para usted. Así que no importa cuántas funciones tenga un tipo dado, no es necesario que cambie su tamaño. Cuando te metes en una herencia complicada con funciones virtuales y otras cosas, esto cambia ligeramente, pero al final el número de funciones continúa sin tener impacto en el tamaño final del objeto.
El tamaño inicial de un byte se debe a que todos los objetos tienen que ocupar un espacio, de modo que puede estar garantizado que no hay dos objetos que ocupen el mismo espacio. Considere una matriz ... a[5]
es lo mismo que *(a + 5)
, y agregar a un puntero aumenta la dirección de la memoria según el tamaño del objeto. si sizeof(a)
fuera 0
, entonces todos los elementos de la matriz se colapsarían hasta la misma dirección.
Que el tipo de objetos de un espacio determinado esté obligado por el estándar ... que el tamaño sea exactamente igual a uno no lo es. sizeof(c)
en su caso podría ser 23, pero no hay razón para ello.
Para completar, es posible que un subobjeto tenga un tamaño de cero. La optimización de la base vacía permite que una clase base no ocupe ninguna memoria real si no es necesario. Por lo tanto, sizeof(Base) == sizeof(Derived)
puede ser verdadero, aunque Formalmente Derived
contiene una instancia de Base
oculta en su interior. Esto está permitido por el estándar, pero no lo exige ... MSVC, por ejemplo, no lo utiliza en algunas situaciones.
Su tamaño es de 1, porque no puede ser 0, de lo contrario dos objetos de este tipo no serían direccionables (no podrían diferenciar sus direcciones)