studio sobrecarga programacion móviles desarrollo curso copia constructores aplicaciones c++ default-constructor effective-c++ empty-class

sobrecarga - ¿Qué función escribe y llama C++ en una clase vacía?



manual de programacion android pdf (3)

En el libro Effective C ++ , vi el siguiente pasaje:

Como resultado, si escribes

class Empty{};

Es esencialmente lo mismo que si hubieras escrito esto:

class Empty { public: Empty() { ... } Empty(const Empty& rhs) { ... } ~Empty() { ... } Empty& operator=(const Empty& rhs) { ... } // copy assignment operator };

El siguiente código hará que se genere cada función:

Empty e1; Empty e2(e1); e2 = e1;

Pero después de desensamblar el archivo ejecutable que se creó al compilar el código anterior, me di cuenta de que no es así: no se invoca ninguna función.

Aquí está el código de montaje principal:

00000000004006cd <main>: 4006cd: 55 push %rbp 4006ce: 48 89 e5 mov %rsp,%rbp 4006d1: b8 00 00 00 00 mov $0x0,%eax 4006d6: 5d pop %rbp 4006d7: c3 retq

No hay ninguna función llamada "Vacío" en el segmento .text .

Entonces, ¿cuál es realmente el comportamiento de un compilador después de que llamemos a un constructor o asignación de una clase vacía? ¿Genera algunas funciones como decía el libro? Si es así, ¿dónde se almacenan?


Esos métodos se generan para la clase, pero se generan como "en línea".

Como son implementaciones miembro por miembro (por ejemplo, el constructor de copia copiará y construirá todos los miembros) cuando la class esté vacía, entonces no se hace nada en ellos, y al estar en línea son simplemente invisibles.

Sin embargo, es muy importante recordar que esos métodos obtienen automáticamente una implementación ... por ejemplo, el código

struct Foo { char *buf; Foo() : buf(new char[10]) {} ~Foo() { delete[] buf; } };

está defectuoso, porque el código generado automáticamente para el constructor de copia y la asignación es incorrecto y dará lugar a la eliminación múltiple del búfer.

Es un buggy no por algo que se ha escrito, sino por algo que no se ha escrito y esto es complicado. Por eso es extremadamente importante recordar lo que C ++ escribirá automáticamente para usted: si esa implementación es lo que desea, entonces es perfecta, pero si no, entonces corríjala proporcionando la implementación correcta o prohibiendo la creación o uso de ese código incorrecto.


Las funciones existen, pero pueden estar en línea.

Cuando el compilador en línea las funciones, se da cuenta de que son no-ops, y no se genera ningún código.

Lo que dice el libro es cierto hasta cierto punto, las funciones nocionales son creadas por el compilador, para llamadas en línea y directas.

Pero el código generado está vacío, por lo que un compilador de optimización eliminará cualquier evidencia de la función (configurando este puntero), y las funciones nunca serán llamadas directamente.

El libro no está realmente tratando de explicar el código generado, sino el impacto de crear una clase y las funciones "ocultas" que genera para el funcionamiento normal.


Usted y el libro están llegando a esta situación desde diferentes niveles de abstracción.

El libro utiliza el término "generado" para referirse a las funciones de C ++ definidas implícitamente por el compilador en el programa abstracto de C ++. Esto absolutamente sucede.

Lo estás interpretando como la generación real de código de máquina real en el programa traducido. Eso no es lo que significa. La generación del código de máquina real siempre está sujeta a los caprichos del compilador, siempre y cuando se mantenga la semántica de su programa abstracto original.

Como tal, el libro ciertamente no es incorrecto, aunque probablemente habría usado una palabra diferente en aras de la claridad. Apegarse a la terminología estándar nunca duele.