tablas tabla resueltos para histograma frecuencias frecuencia estadistica ejercicios ejemplos distribucion descriptiva c++ inheritance sizeof language-lawyer

tabla - ¿Se permite que C++ aumente el tamaño de clase derivado si no hay nuevas variables de miembro en comparación con la clase base?



tablas de frecuencia ejercicios para resolver (4)

Desde 5.3.2 [expr.sizeof]

Cuando se aplica a una clase, el resultado [de sizeof ] es el número de bytes en un objeto de esa clase, incluido cualquier relleno requerido para colocar objetos de ese tipo en una matriz. El tamaño de la clase más derivada será mayor que cero (1.8).

Desde 1.8 [intro.object]

A menos que sea un campo de bits (9.6), el objeto más derivado tendrá un tamaño distinto de cero y ocupará uno o más bytes de almacenamiento. Los sub-objetos de la clase base pueden tener un tamaño cero. Un objeto de tipo POD (3.9) ocupará bytes de almacenamiento contiguos.

y una nota:

El tamaño real de un subobjeto de clase base puede ser menor que el resultado de aplicar sizeof al subobjeto, debido a las clases base virtuales y los requisitos de relleno menos estrictos en los subobjetos de clase base.

Júntelos y creo que lo que le está diciendo es que no tiene garantías en absoluto sobre qué sizeof podría decirle, salvo que el resultado será mayor que cero. De hecho, ni siquiera parece garantizar que sizeof(Derived) >= sizeof(Base) !

Supongamos que tengo una clase base con algunas variables miembro y sin funciones virtuales:

class Base { int member; };

y una clase derivada que deriva de forma no virtual de Base y no tiene nuevas variables miembro y tampoco funciones virtuales:

class Derived : Base { };

Obviamente sizeof(Derived) no puede ser más pequeño que sizeof(Base) .

¿Se requiere que sizeof(Derived) sea ​​igual a sizeof(Base) ?


Interesante pregunta. Tengo un ejemplo en el que una clase derivada con un campo adicional es del mismo tamaño que una clase base vacía . (Esto debería ser un comentario, pero es demasiado grande, por favor acepte una de las otras respuestas, aunque los votos positivos son bienvenidos si es interesante).

Considere este trivial programa de C ++:

class A {}; class B : public A { int m_iInteger; }; int _tmain(int argc, _TCHAR* argv[]) { printf("A: %d/r/n", sizeof(A)); printf("B: %d/r/n", sizeof(B)); printf("int: %d/r/n", sizeof(int)); return 0; }

¿Cuál esperaría que fuera la salida, si sizeof(int) es 4? Quizás algo como:

A: 0 B: 4 int: 4

?

Mi compilador - Embarcadero C ++ Builder 2010 - da la salida:

A: 8 B: 8 int: 4

En otras palabras, agregar un campo extra en la clase derivada no hace que la clase derivada sea más grande.

Hay una idea de por qué con el tema del archivo de ayuda sobre la opción de compatibilidad Clase base vacía de longitud cero .

Por lo general, el tamaño de una clase es de al menos un byte, incluso si la clase no define ningún miembro de datos. Cuando establece esta opción, el compilador ignora este byte no utilizado para el diseño de la memoria y el tamaño total de las clases derivadas; las clases base vacías no consumen espacio en las clases derivadas. Predeterminado = Falso

Parece que el tamaño de una clase con configuraciones de compilador predeterminadas para este compilador es de 8 bytes, no de uno, y de hecho el cambio de esta configuración para este ejemplo de código no tiene ningún efecto.

También puede encontrar interesante este artículo sobre el tamaño de las clases base y la optimización anterior . Discute por qué las clases deben tener un tamaño de al menos un byte, lo que hace la optimización, y profundiza en la representación de las funciones miembro, etc. también:

De hecho, el estándar requiere que el tamaño de un objeto nunca sea cero; también requiere que en un objeto derivado, los miembros de la (s) clase (s) base aparezcan antes de los miembros de datos declarados por el usuario de la clase derivada. Sin embargo, un subobjeto de clase base no se considera un objeto completo. Por lo tanto, es posible eliminar el subobjeto de clase base del objeto derivado sin violar las reglas. En otras palabras, en el objeto t, el desplazamiento de S y x puede superponerse ...

Por favor, lea el artículo para el contexto completo de esa cita.


No hay tal requisito.

La única parte relevante del lenguaje en que puedo pensar es que cada objeto, ya sea completo o no, y ya sea derivado o no, tiene una identidad , que viene dada por el par de su dirección y su tipo. Cf. C ++ 11 1.8 / 6:

Dos objetos que no son campos de bits pueden tener la misma dirección si uno es un subobjeto de la otra, o si al menos uno es un subobjeto de clase base de tamaño cero y son de tipos diferentes; de lo contrario, deberán tener direcciones distintas.

Por lo tanto, tanto el objeto derivado más como el subobjeto base de su ejemplo deben tener identidades distintas.

Ciertamente, tendría sentido para un compilador dar a Base y Derived un tamaño de 1 , pero esto no es obligatorio. Sería aceptable si la Base tenía el tamaño 1729 y Derived tenía el tamaño 2875.


class Base { // int member; I have just created an empty base class. }; class Derived : Base { };

Ahora el compilador gcc daría "tamaño> 0" para los objetos creados por las clases Base y Derivadas. El compilador gcc solo proporciona la presencia de la dirección de los objetos al usuario.

Note:Derived class would contain base class members, so obviously we can think of sizeof(derived class) greater then sizeof(base class). But this depends on the compiler if it allocates some extra space while defining the derived class.

Mi presente compilador gcc mostró el tamaño de los objetos de Base y Derivados para ser el mismo.