c++ - keywords - ¿Ejemplo de encabezado privado/público?
meta tags ejemplos (5)
¿Puede alguien darme un ejemplo de cómo funcionan los encabezados públicos y privados? He leído algo en la red pero parece que no puedo encontrar mucha información útil con códigos de muestra. Me recomendaron que debería usar encabezados privados para separar las partes públicas y privadas de mi código para crear una biblioteca estática. Después de una lectura, tengo una idea general de cómo funciona, pero realmente apreciaría un buen ejemplo para que empiece. Específicamente, lo que no entiendo es cómo colocar las funciones de la interfaz en mi encabezado público y las variables / funciones privadas en mi encabezado privado. ¡Gracias!
EDITAR:
Tal vez no esté redactando correctamente mi pregunta, pero lo que quise decir es, por ejemplo, tengo myMath.h y myMath.cpp, y myMath.h tiene:
class myMath{
public:
void initialise(double _a, double _b);
double add();
double subtract();
private:
double a;
double b;
};
Y myMath.cpp tiene las implementaciones de las funciones. ¿Cómo puedo hacer que myMath.h solo tenga las tres funciones públicas, y las variables privadas se definan en otro archivo (por ejemplo, myMath_i.h), y estos tres archivos se encuentren de tal manera que después de crear una biblioteca estática, solo myMath.h es necesario para los usuarios. Esto también significa que myMath.h no puede #incluir myMath_i.h. Así que algo como:
myMath.h:
class myMath{
public:
void initialise(double _a, double _b);
double add();
double subtract();
}
y myMath_i.h:
class myMath{
private:
double a;
double b;
}
Por supuesto, eso no es posible porque entonces estaré redefiniendo la clase myMath ...
De hecho, he encontrado que el enfoque de dos encabezados, una fuente, es frágil. Si olvida actualizar el encabezado ''público'' después de cambiar el encabezado ''privado'', su código puede compilarse, y luego segfault en otro lugar durante el tiempo de ejecución. Me ha pasado esto varias veces, así que prefiero escribir código que no se compile a menos que todo sea correcto.
MyClass.cpp se implementa de esta manera:
#define MYCLASS_IMPL
#include "MyClass.h"
// Implementation follows
...
MyClass.h es el bit interesante:
#ifdef MYCLASS_IMPL
#include everything needed for the private: section
#endif
#include everything needed for the public: section only
class MyClass
{
public:
// Everything that''s public
#ifdef MYCLASS_IMPL
private:
// Implementation details
#endif
};
Si el objetivo es ocultar los detalles de la implementación (por ejemplo, para una biblioteca cerrada), es posible que deba ir con el enfoque de dos encabezados. Si no desea arrastrar dependencias solo para usar una clase, el enfoque de encabezado único puede ser una solución simple y robusta.
Para abordar la pregunta de Arton: Ha pasado un tiempo desde que lo he visto, pero creo que el problema tenía que ver con la creación de instancias de objetos basados en el encabezado público, y luego asumir un tamaño de objeto diferente con el encabezado privado. En el tiempo de ejecución, un desplazamiento en el objeto no coincidiría, lo que provocaría un choque de memoria. Parece que la respuesta de erenlender cubre este caso con un par de clases público / privado.
Los encabezados públicos son aquellos que necesitan los usuarios de la biblioteca. Los encabezados privados son los necesarios para compilar la biblioteca, pero no son necesarios para los usuarios de la biblioteca. Realizar la división puede ser bastante complicado, y muchas bibliotecas simplemente no se molestan.
Me preguntaba lo mismo ya que estoy cambiando de C a C ++ como mi lenguaje de programación principal. Supongo que la mejor manera es usar interfaces (clases abstractas en C ++): publica una interfaz pública y su implementación privada solo usa la interfaz como clase base.
Puede declarar todas las interfaces y constantes que desea exponer al usuario de la biblioteca en un archivo de encabezado separado (o un conjunto de archivos) y colocarlo en el subdirectorio "inc"; esos encabezados serán "públicos". También utilizará otros archivos de encabezado para declarar clases y cosas que no desea exponer, ya que estos son detalles de la implementación. Colocará esos archivos en el subdirectorio "src", que serán "privados".
De esta manera, al usuario se le dará una pista de que debe incluir solo los encabezados públicos, aquellos que están en "inc" y solo esos encabezados contienen lo que realmente necesita, mientras que todos los demás encabezados son "privados" y por su interés. Área a menos que quiera leer en la implementación.
Cuando publica su biblioteca como binario, ya sea biblioteca estática o dinámica, solo copia los contenidos "inc" y el resultado de la compilación, son suficientes para el usuario y de esta manera no ve sus fuentes de implementación.
Tiene dos archivos de encabezado MyClass.h y MyClass_p.h y un archivo de origen: MyClass.cpp.
Echemos un vistazo a lo que hay dentro de ellos:
MyClass_p.h:
// Header Guard Here
class MyClassPrivate
{
public:
int a;
bool b;
//more data members;
}
MyClass.h:
// Header Guard Here
class MyClassPrivate;
class MyClass
{
public:
MyClass();
~MyClass();
void method1();
int method2();
private:
MyClassPrivate* mData;
}
MyClass.cpp:
#include "MyClass.h"
#include "MyClass_p.h"
MyClass::MyClass()
{
mData = new MyClassPrivate();
}
MyClass::~MyClass()
{
delete mData;
}
void MyClass::method1()
{
//do stuff
}
int MyClass::method2()
{
return stuff;
}
Mantenga sus datos en MyClassPrivate y distribuya MyClass.h.