¿Por qué necesitamos poner miembros privados en los encabezados?

56

Las variables privadas son una forma de ocultar la complejidad y los detalles de la implementación al usuario de una clase. Esta es una característica bastante agradable. Pero no entiendo por qué en c ++ necesitamos ponerlos en el encabezado de una clase. Veo dos inconvenientes molestos a esto:

  • Se desordena el encabezado del usuario
  • Fuerza la compilación de todas las bibliotecas de clientes siempre que se modifiquen las partes internas

¿Hay una razón conceptual detrás de este requisito? ¿Es solo para facilitar el trabajo del compilador?

    
pregunta Simon 10.04.2012 - 11:25

3 respuestas

64

Es porque el compilador de C ++ debe conocer el tamaño real de la clase para poder asignar la cantidad correcta de memoria en la instanciación. Y el tamaño incluye todos los miembros, también los privados.

Una forma de evitar esto es utilizando el Pimpl idiom , explicado por Herb Sutter en su serie Guru of the Week # 24 y # 28 .

Actualizar

De hecho, esto (o más generalmente, la distinción entre el encabezado y el archivo fuente y #include s) es un obstáculo importante en C ++, heredado de C. En los días en que se creó C ++ C aún no había experiencia con el desarrollo de software a gran escala, donde esto comienza a causar problemas reales. Las lecciones aprendidas desde entonces fueron atendidas por diseñadores de lenguajes más nuevos, pero C ++ está sujeto a requisitos de compatibilidad con versiones anteriores, lo que hace que sea muy difícil abordar un problema tan fundamental en el lenguaje.

    
respondido por el Péter Török 10.04.2012 - 11:53
15

La definición de la clase debe ser suficiente para que el compilador produzca un diseño idéntico en la memoria siempre que haya utilizado un objeto de la clase. Por ejemplo, dado algo como:

class X { 
    int a;
public:
    int b;
};

El compilador normalmente tendrá a en el desplazamiento 0 y b en el desplazamiento 4 . Si el compilador vio esto solo:

class X { 
public:
    int b;
};

"Pensaría" que b debería estar en el offset 0 en lugar del offset 4. Cuando el código que usa esa definición se asigna a b , el código que usa la primera definición vería que a se modifica y viceversa.

La forma habitual de minimizar los efectos de realizar cambios en las partes privadas de la clase suele denominarse el idioma pimpl (sobre el cual estoy seguro de que Google puede proporcionar gran cantidad de información).

    
respondido por el Jerry Coffin 10.04.2012 - 11:57
3

Probablemente hay varias razones. Si bien la mayoría de las otras clases no puede acceder a los miembros privados, a las clases de amigos todavía se les puede acceder. Entonces, al menos en este caso, pueden ser necesarios en el encabezado, para que la clase de amigos pueda ver que existen.

La recompilación de archivos dependientes puede depender de su estructura de inclusión. Incluir los archivos .h en un archivo .cpp en lugar de otro encabezado puede, en algunos casos, evitar largas cadenas de recompilaciones.

    
respondido por el thorsten müller 10.04.2012 - 11:40

Lea otras preguntas en las etiquetas