una resueltos resolucion programacion orientada operador objetos miembros ejercicios ejemplos codigo clases clase ambito c++

resueltos - operador de resolucion de ambito c++



¿Es posible imprimir el tamaño de una clase de C++ en tiempo de compilación? (10)

¿Es posible determinar el tamaño de una clase de C ++ en tiempo de compilación?

Me parece recordar un método de meta-programación de plantilla, pero podría estar equivocado ...

lo siento por no ser más claro: quiero que el tamaño se imprima en la ventana de salida de compilación


¿Qué pasa con sizeof ? Esto debería funcionar en objetos y clases.

void foo( bar* b ) { int i = sizeof bar; int j = sizeof *b; // please remember, that not always i==j !!! }

Editar:

Este es el ejemplo en el que estaba pensando, pero por alguna razón no funciona. ¿Alguien puede decirme qué pasa?

#include <iostream> using namespace std; class bar { public: int i; bar( int ii ) { i = ii; } virtual ~bar(){ i = 0; } virtual void d() = 0; }; class bar2: public bar { public: long long j; bar2( int ii, long long jj ):bar(ii){ j=jj; } ~bar2() { j = 0; } virtual void d() { cout << "virtual" << endl; }; }; void foo( bar *b ) { int i = sizeof (bar); int j = sizeof *b; cout << "Size of bar = " << i << endl; cout << "Size of *b = " << j << endl; b->d(); } int main( int arcc, char *argv[] ) { bar2 *b = new bar2( 100, 200 ); foo( b ); delete b; return 0; }

La aplicación se ejecutó en Linux (gcc 4.4.2):

[elcuco@pinky ~/tmp] ./sizeof_test Size of bar = 8 Size of *b = 8 virtual


Aquí hay una versión que produce una advertencia en lugar de un error:

/** Compile-time sizeof as a warning so compilation can continue */ struct TestStruct { int i1; float f1; const char* pchar1; double d1; char c1; void* pv1; bool b1; }; template<unsigned int n> struct PrintNum { enum { value = n }; }; template<int number> struct _{ operator char() { return number + 256; } }; #define PRINT_AS_WARNING(constant) char(_<constant>()) int main() { PRINT_AS_WARNING(PrintNum<sizeof(TestStruct)>::value); return 0; }

Véalo corriendo here . Como un aparte, puedes leer el tamaño ( 48 ) directamente desde el ensamblado allí:

leaq -1(%rbp), %rax movq %rax, %rdi call _<48>::operator char() movl $0, %eax leave ret


Esta macro se basa en la respuesta de grep. Defina la macro como a continuación:

#define COMPILE_TIME_SIZEOF(t) template<int s> struct SIZEOF_ ## t ## _IS; / struct foo { / int a,b; / }; / SIZEOF_ ## t ## _IS<sizeof(t)> SIZEOF_ ## t ## _IS;

Entonces úsalo así:

COMPILE_TIME_SIZEOF(long);

Y obtendrás un resultado similar al siguiente:

error: ''SIZEOF_long_IS<4> SIZEOF_long_IS'' redeclared as different kind of symbol SIZEOF_ ## t ## _IS<sizeof(t)> SIZEOF_ ## t ## _IS;

Todavía es una solución alternativa, pero lo suficientemente fácil de usar.


Este es el fragmento, que uso:

template <typename T> void get_sizeof() { switch (*((int*)0x1234)) { case sizeof(T): case sizeof(T):; } }

Para obtener el tamaño, ejemplifique la función en cualquier parte del código, por ejemplo, dentro de una declaración:

struct S { long long int ill; }; get_sizeof<S>;

El error se verá así:

error: duplicate case value ''8'' switch (*((int*)0x1234)) { case sizeof(T): case sizeof(T):; } ^


Hay operador sizeof( int ) , sizeof( char ) así que creo que es posible y la llamada probablemente se vea como sizeof( MyClass )


Otro truco con código más simple:

int dummy; switch (dummy) { case sizeof(dummy): case sizeof(dummy): break; }

------ Build started: Project: cpptest, Configuración: Debug Win32 ------> cpptest.cpp c: / work / cpptest / cpptest / cpptest.cpp (33): error C2196: valor de caso ''4 '' ya usado

========== Build: 0 exitoso, 1 fallido, 0 actualizado, 0 omitido ==========

EDITAR: el dummy anterior es una variable integral para la condición del interruptor para satisfacer la sintaxis requerida. Use sizeof(X) para la constante de mayúsculas y minúsculas:

Esto también funciona para el código C.

struct X { int a,b; int c[10]; }; int _tmain(int argc, _TCHAR* argv[]) { int dummy; switch (dummy) { case sizeof(X): case sizeof(X): break; } return 0; }

------ Build started: Project: cpptest, Configuración: Debug Win32 ------ cpptest.cpp c: / work / cpptest / cpptest / cpptest.cpp (29): error C2196: valor de caso ''48'' ya usado ========== Build: 0 exitoso, 1 fallido, 0 actualizado, 0 omitido ==========


Para responder a la pregunta actualizada, esto puede ser excesivo, pero imprimirá los tamaños de tus clases en tiempo de compilación. Hay un modificador de línea de comandos no documentado en el compilador de Visual C ++ que mostrará los diseños completos de las clases, incluidos sus tamaños:

Ese modificador es / d1reportSingleClassLayoutXXX, donde XXX realiza coincidencias de subcadena con el nombre de clase.

http://blogs.msdn.com/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual-c-and-fixing-lnk2022.aspx


Si realmente necesita obtener sizeof (X) en la salida del compilador, puede usarlo como parámetro para un tipo de plantilla incompleto:

template<int s> struct Wow; struct foo { int a,b; }; Wow<sizeof(foo)> wow; $ g++ -c test.cpp test.cpp:5: error: aggregate ‘Wow<8> wow’ has incomplete type and cannot be defined


Sin embargo, otro truco que hace que el compilador de VC ++ 2010 se queje sobre el uso incorrecto del entero de tiempo de compilación:

// cpptest.cpp : Defines the entry point for the console application. // #include "stdafx.h" struct X { int a[11]; char c[2]; }; void proc1(void* s[1]) { } int _tmain(int argc, _TCHAR* argv[]) { int b[sizeof(X)]; proc1(b); return 0; }

1> ------ Build started: Project: cpptest, Configuration: Release Win32 ------ 1> cpptest.cpp 1> cpptest.cpp (14): error C2664: ''proc1'': no ​​se puede convertir el parámetro 1 de ''int [48]'' a ''void * []'' 1>
Los tipos apuntados no están relacionados; la conversión requiere reinterpret_cast, fundido de estilo C o fundido de estilo funcional ========== Build: 0 exitoso, 1 fallido, 0 actualizado, 0 omitido ==========

Por lo tanto, sizeof (struct X) es 48. Esto también funciona para el código C.


sizeof () determina el tamaño en el tiempo de compilación.

No funciona hasta el momento de la compilación, por lo que no puede usarlo con el preprocesador.