Tamaño de una clase en C ++ | El relleno, la alineación de la clase | Tamaño de clase derivada

En este artículo, vamos a ver Cuál es el tamaño de una clase y un objeto en C ++? También vamos a aprender lo que es el relleno, la alineación proporcionada por el compilador while definir la memoria para una clase. Además, hemos ampliado la idea en case de encontrar el tamaño del objeto de clase derivada también.

Requisito:

  • sizeof () operador en C / C ++
  • Tamaño de struct en C

Sabemos que un tamaño struct no es sólo la suma de todos los miembros de datos, sino que es la suma mínima garantizada. El compilador agrega un poco de relleno para la alineación miembro de datos.

En la clase de C ++, las cosas son exactamente lo mismo que un struct. Sin embargo, hay algunas cosas más.

En primer lugar, while en C ++ hay funciones miembros, miembros de datos static. Do los tienen ninguna contribución al tamaño de la clase, los objetos?

La respuesta es no. Sólo los miembros no static datos contribuyen al tamaño de clase y objetos. Esto se debe a que los miembros static tienen sólo una instancia que es compartida entre todos los objetos. Y funciones miembro normales son como código ejecutable que no tiene el tamaño como miembros de datos.

Al igual que en la clase siguiente,

class A {
private:
static int i;
int a;
char b;
public:
A()
{
a = 0;
b = '#';
}
A(int aa, char bb)
{
a = aa;
b = bb;
}
int get_int()
{
cout << a << endl;
return a;
}
char get_char()
{
cout << b << endl;
return b;
}
};

Tamaño de la clase debe ser la suma de todo el miembro de datos static no + relleno, que es como a continuación:

Size of a class in C++ | Padding, alignment in class | Size of derived class - 4

Por encima es la alineación de la clase A y que de ¿Por qué el tamaño de la clase es de 8 bytes . Static miembros de datos y las funciones miembro no tienen ninguna contribución.

Cómo compilador añade el relleno?

Ahora la pregunta es cómo compilador añade el relleno y alineación? El método es dependiente y compilador tipo de codiciosos. Se alinea hasta el límite de la memoria máxima que se destina.

Aquí nos encontramos con que la memoria máxima asignada es de 8 bytes, por lo tanto todos los miembros de datos adquieren 8 bytes y el tamaño total es de 32 bytes. Ahora la pregunta es ¿ocurrirá cada vez de manera similar?

¿Es como el número de miembros de datos * El tamaño máximo de tipo de datos?

La respuesta es no. Se tratará de alinear de manera óptima manteniendo el mismo orden. Para comprobar un ejemplo por favor, siga el artículo sobre tamaño de la estructura en C. Además, más adelante en este artículo, tenemos ejemplos de tales.

Tamaño de una clase derivada

¿Cuál es el tamaño de una clase derivada? Por supuesto, una clase derivada tiene todos los miembros de datos de la clase base que hereda y lo hace ha copiado su propio de esos miembros de datos también. Por lo tanto el tamaño debe ser el tamaño de los miembros de datos de la clase base + de tamaño de los datos de clase derivadas.

cheque de Let el siguiente código y la salida.

En la estructura anterior, nos encontramos con que el tamaño es de 24 bytes, aunque los mismos miembros de datos se han utilizado. Esto se debe al cambio en el orden de la declaración de miembro. En este case, la alineación y el relleno sería como a continuación:

#include <bits/stdc++.h>
using namespace std;
class Base {
protected:
static int i;
int a;
char b;
public:
Base()
{
a = 0;
b = '#';
}
Base(int aa, char bb)
{
a = aa;
b = bb;
}
int get_int()
{
cout << a << endl;
return a;
}
char get_char()
{
cout << b << endl;
return b;
}
};
class Derived : public Base {
private:
int c;
char d;
public:
Derived()
{
c = 0;
d = '#';
}
Derived(int cc, char dd)
{
c = cc;
d = dd;
}
int get_int()
{
cout << c << endl;
return c;
}
char get_char()
{
cout << d << endl;
return d;
}
};
int main()
{
Base b;
Derived d;
printf("Size of class Base: %lun", sizeof(Base));
printf("Size of object b: %lun", sizeof(b));
printf("Size of class Derived: %lun", sizeof(Derived));
printf("Size of object d: %lun", sizeof(d));
return 0;
}

salida:

Size of class Base: 8
Size of object b: 8
Size of class Derived: 16
Size of object d: 16

Así que aquí el tamaño del objeto de clase base es de 8 bytes, mientras que el tamaño del objeto de clase derivada es 16 bytes.

Para la clase base es similar, como a continuación:

Size of a class in C++ | Padding, alignment in class | Size of derived class - 5

While para la clase derivada es como:

Size of a class in C++ | Padding, alignment in class | Size of derived class - 6

Así que lo es el orden de los miembros de datos son objeto de mantenimiento. Y puesto que sabemos que el constructor de la clase base se invocó por primera vez, es por eso que los miembros de la clase de base son lo primero.

Ahora vamos a cambiar el orden del miembro de datos en la clase derivada y comprobar el tamaño de la clase & amp; objeto.

#include <bits/stdc++.h>
using namespace std;
class Base {
protected:
static int i;
int a;
char b;
public:
Base()
{
a = 0;
b = '#';
}
Base(int aa, char bb)
{
a = aa;
b = bb;
}
int get_int()
{
cout << a << endl;
return a;
}
char get_char()
{
cout << b << endl;
return b;
}
};
class Derived : public Base {
private:
char d;
int c;
public:
Derived()
{
c = 0;
d = '#';
}
Derived(int cc, char dd)
{
c = cc;
d = dd;
}
int get_int()
{
cout << c << endl;
return c;
}
char get_char()
{
cout << d << endl;
return d;
}
};
int main()
{
Base b;
Derived d;
printf("Size of class Base: %lun", sizeof(Base));
printf("Size of object b: %lun", sizeof(b));
printf("Size of class Derived: %lun", sizeof(Derived));
printf("Size of object d: %lun", sizeof(d));
return 0;
}

de salida:

Size of class Base: 8
Size of object b: 8
Size of class Derived: 12
Size of object d: 12

Simplemente cambiando el orden de miembro, se encontró que clase derivada está teniendo tamaño 12 Bytes ahora. Así que tiene que haber alguna mejor alineación ahora.

Así, como podemos pensar en compilador fuimos para la alineación codiciosos y ahora es capaz de alinear de manera óptima (Recuerde compilador can & rsquo; t el cambio del orden del miembro de datos).

Size of a class in C++ | Padding, alignment in class | Size of derived class - 7

Por encima es la alineación para la clase derivada y ahora el tamaño es 12 bytes, en lugar de 16 a causa de la alineación anterior. Vimos que el compilador mantiene la alineación con avidez & amp; Es por eso que alinea char b del miembro de clase base & amp; char d, que es su miembro, en la misma fila. Cuando se intentó alinear int c, podría no tan sólo quedaban 2 bytes. Pero en lugar de int, if era char sólo entonces se habría alineado en la misma línea.

La palabra clave virtual y su efecto sobre el tamaño

Sabemos en la clase derivada puede heredar la clase base como virtual también. ¿Cuál sería el tamaño de la clase derivada en ese case? ¿Habrá algún cambio?

La respuesta es sí. Habrá un adicional de 8 bytes que no es sino el tamaño de VTPR (puntero de la tabla virtual) es

Así, para el ejemplo de primera clase derivada, tenemos 16 Bytes, pero aquí hemos añadido la palabra clave virtual y tiene el tamaño de 24 bytes que es debido al tamaño de VTPR.

#include <bits/stdc++.h>
using namespace std;
class Base {
protected:
static int i;
int a;
char b;
public:
Base()
{
a = 0;
b = '#';
}
Base(int aa, char bb)
{
a = aa;
b = bb;
}
int get_int()
{
cout << a << endl;
return a;
}
char get_char()
{
cout << b << endl;
return b;
}
};
class Derived : virtual public Base {
private:
char d;
int c;
public:
Derived()
{
c = 0;
d = '#';
}
Derived(int cc, char dd)
{
c = cc;
d = dd;
}
int get_int()
{
cout << c << endl;
return c;
}
char get_char()
{
cout << d << endl;
return d;
}
};
int main()
{
Base b;
Derived d;
printf("Size of class Base: %lun", sizeof(Base));
printf("Size of object b: %lun", sizeof(b));
printf("Size of class Derived: %lun", sizeof(Derived));
printf("Size of object d: %lun", sizeof(d));
return 0;
}

Salida:

Size of class Base: 8
Size of object b: 8
Size of class Derived: 24
Size of object d: 24

lo tanto, aquí nos ocurrió la idea de un tamaño normal de clases y objetos. Hemos aprendido cómo se alinea el compilador miembros de datos y agregar relleno. Además, hemos ampliado la discusión con el tamaño de la clase derivada.

Para finalizar la discusión me dejaron de tirar un desafío para la mente. Lo do usted que sería el tamaño de una clase vacía?

Do cree que es 0?

#include <bits/stdc++.h>
using namespace std;
class A {
};
int main()
{
printf("Size of class A: %lun", sizeof(A));
return 0;
}

Salida:

Size of class A: 1

Bueno, el tamaño de la clase vacía no es 0. Esto es en realidad para asegurarse de que dos objetos diferentes tendrán diferentes direcciones.


Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *