Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: Pogacha en 05 de Octubre de 2005, 01:01:30 PM

Título: Cosas Ocultas En Una Lib
Publicado por: Pogacha en 05 de Octubre de 2005, 01:01:30 PM
 Se puede de alguna forma hacer una .lib que tenga cosas ocultas en una clase sin que sea una clase virtual?

o sea ... que en verdad sea:
class {
  int mimiembro_oculto;
 public:
   miclase();
};

y la cabecera que el usuario de la lib vea:
class {
  public:
    miclase();
};

Haciendola virtual puedo pero no se como hacerla normal.

Saludos y gracias de antemano
Título: Cosas Ocultas En Una Lib
Publicado por: Topper en 05 de Octubre de 2005, 01:15:44 PM
 creo haber entendido tu pregunta ...  :ph34r:

Has probado con Protected o Private?

Protected: Sólo es accesible desde clases heredadas y private sólo es accesible desde la propia clase.


class {
public:
  miclase();
private:
  int mimiembro_oculto;
};

class {
public:
  miclase();
protected:
  int mimiembro_oculto;
};
Título: Cosas Ocultas En Una Lib
Publicado por: _Grey en 05 de Octubre de 2005, 01:21:28 PM
 La ocultacion de la implementacion, o las clases proxy, es lo que estas buscando.

A ver como lo explico de forma que se me entienda.....

Al usuario le das un .h con la clase "proxy", con las funciones que quieras pueda ver. Luego en la .cpp (que no se la das, esta claro,no?), lo que haces, es que cada funcion llame a su homologa de la clase que estas ocultando.

A ver, con un ejemplo....:

claseproxy.h

class claseReal;

class claseProxy{
void loQueSea();
private:
claseReal *cr;
};


clasereal.h

class claseReal{
void loQueSea();
private:
int montones_de_variables;
};


claseproxy.cpp

#include "claseproxy.h"
#include "clasereal.h"
claseProxy::claseProxy(){
cr = new claseReal ();
}
claseProxy::~claseProxy(){
delete cr;
}
void claseProxy::loQueSea(){
cr->loQueSea();
}


clasereal.cpp

#include "clasereal.h"
void claseReal::loQueSea(){
tu codigo...
}


basicamente le das al usuario solo la "claseproxy.h", y si , tendras que tirar de un punterito en la clase proxy. Y si no te gusta usas una interface, Ala!

Saludos!!.

PD: Es algo enrebasado espero se comprenda...
Título: Cosas Ocultas En Una Lib
Publicado por: TheAzazel en 05 de Octubre de 2005, 01:25:33 PM
 Exacto, grey se me adelanto... asi lo he hecho yo con CRM32Pro.... para que desde el punto de vista del usuario final(programador) no tenga porque liarse con cosas que no puede utilizar :)

Y la verdad que el codigo queda mas limpio en el .h de cara al usuario final... no asi tu propio codigo, que tiene un poco mas de engorro, pero es manejable...
Título: Cosas Ocultas En Una Lib
Publicado por: Topper en 05 de Octubre de 2005, 01:36:52 PM
 Vaya, no había caído en los patrones de diseño. Buen apunte chavales...  (ole)  
Título: Cosas Ocultas En Una Lib
Publicado por: Pogacha en 05 de Octubre de 2005, 01:46:54 PM
 Pero entonces es mas facil tener una clase virtual y una clase interface ...  
Título: Cosas Ocultas En Una Lib
Publicado por: ShAq en 05 de Octubre de 2005, 01:48:49 PM
 una cosa, y simplemente borrando lo que no quieres que se vea del .h para el usuario??
yo en mi libreria LTML, simplemente borré las variables miembro de las clases y dejé
los métodos y me funcionó...
Título: Cosas Ocultas En Una Lib
Publicado por: Topper en 05 de Octubre de 2005, 02:53:10 PM
 
Citaruna cosa, y simplemente borrando lo que no quieres que se vea del .h para el usuario??

hombre, para hacer eso creo que sería más elegante dejar esas variables miembro como privadas o protegidas, aunque la opción del proxy que han comentado me parece la más adecuada.

Saludos.
Título: Cosas Ocultas En Una Lib
Publicado por: zupervaca en 05 de Octubre de 2005, 04:07:25 PM
 los dos sistemas estan bien aunque tiene sus pros y sus contras, por ejemplo, el proxy queda muy elegante, pero implica tener que escribir codigo cada vez que cambiamos la clase aunque tambien da la ventaja de solventar problemas si la clase cambia y queremos mantener compatible todas las aplicaciones, el otro sistema es que se ha utilizado siempre y da la ventaja de que cuando cambias la clase solo tienes que borrar los miembros que no quieres que se vean otro .h
Título: Cosas Ocultas En Una Lib
Publicado por: ethernet en 05 de Octubre de 2005, 04:34:23 PM
 Cual es la razón para querer ocultar una variable? que el coder no pueda cambiarla de propiedad y mangarla ?
Título: Cosas Ocultas En Una Lib
Publicado por: zupervaca en 05 de Octubre de 2005, 04:45:43 PM
 en principio el ocultar un miembro es por que sea protegido o privado, a mi solo se me ocurren esos casos
Título: Cosas Ocultas En Una Lib
Publicado por: Pogacha en 05 de Octubre de 2005, 05:17:54 PM
 
Cita de: "ShAq"una cosa, y simplemente borrando lo que no quieres que se vea del .h para el usuario??
yo en mi libreria LTML, simplemente borré las variables miembro de las clases y dejé
los métodos y me funcionó...
Perdon la demora en contestar ...
Eso me da un poco de miedo, pues en un new MiClase; cuanta memoria se reserva? ni te cuento en un MiClase[3000]. Si bien las declaraciones de funciones no tienen problema, no se quien dice cuanta memoria tiene un objeto (el constructor?) o si es legal declarar dos clases con distintas con mismo nombre, no tengo la menor idea de esto, pero era el camino que me gustaria tomar ... alguien sabe algo de esto? deberia ser un fanatico religioso del C++ ...

CitarCual es la razón para querer ocultar una variable? que el coder no pueda cambiarla de propiedad y mangarla ?
Eso se arreglaria con un private, pero en realidad la idea seria dejar algo mas claro para el usuario de la lib ya que no le interesa como haces tu para hacerlo y a la vez proteger tus secretos  ... así como tambien solo tener que actualizar el .h cuando halla un cambio que al usuario le interese, no por un cambio interno.
Inclusive todo esto ayudaria a la portabilidad.
Ejemplo:

class TPantalla {
 hInstance hinst;
 hWND hwnd;
 DDrawInterface *DDraw;
 Crear_Ventana();
 Crear_DDraw();
public:
     TPantalla(int x, int y, int bpp);
     ~TPantalla();
};


Ahora si yo le doy un
class TPantalla {
public:
     TPantalla(int x, int y, int bpp);
     ~TPantalla();
};

Al tipo le sentaria mucho mejor, no te parece?

Saludos.
Título: Cosas Ocultas En Una Lib
Publicado por: zupervaca en 05 de Octubre de 2005, 06:17:46 PM
 cada vez que veo ddraw me da vueltas la cabeza jeje

en mi practica con librerias de c++ siempre hay una funcion global o que pertenece a otra clase que nos devuelve la clase creada solucionando el problema que mencionas, un ejemplo de ello se ve en direct3d, siempre que quieres crear un objeto com le pasas un puntero y el te crea el objeto, de esta forma el usuario tendra solo acceso a los miembros que pongas en el .h que le des, pero estaras creando correctamente el objeto ya que lo hace tu libreria, espero que se entienda lo que quiero decir ;)
Título: Cosas Ocultas En Una Lib
Publicado por: _Grey en 05 de Octubre de 2005, 06:46:56 PM
 
CitarPero entonces es mas facil tener una clase virtual y una clase interface ...

De ti depende, pero con la clase proxy, mantienes el funcionamiento de objeto normal que no tendrias con una interface. Ademas puedes meter las funciones de la clase proxy como inline :P .

Citaruna cosa, y simplemente borrando lo que no quieres que se vea del .h para el usuario??
yo en mi libreria LTML, simplemente borré las variables miembro de las clases y dejé
los métodos y me funcionó...

Seguro que funciona, pero entramos en el pantanoso terreno de sin documentar.... casi me extrañaria que fallara pero no lo podriamos descartar, algun experto en el estandard ISO podria ayudar....  :rolleyes:

CitarCual es la razón para querer ocultar una variable? que el coder no pueda cambiarla de propiedad y mangarla ?

Ademas de ocultar las funciones de "utileria" que te has hecho, tanto para que no se metan en tu codigo, como para que no pongan como public, algo que podria romper el funcionamiento del objeto.
Título: Cosas Ocultas En Una Lib
Publicado por: Pogacha en 05 de Octubre de 2005, 09:21:57 PM
 
Cita de: "_Grey"
CitarPero entonces es mas facil tener una clase virtual y una clase interface ...

De ti depende, pero con la clase proxy, mantienes el funcionamiento de objeto normal que no tendrias con una interface. Ademas puedes meter las funciones de la clase proxy como inline :P .
Pero igual así requiere de un trabajo muy extra ya que cada función la tengo que poner 2 veces y no me gusta para nada ...

Como interface y virtual me referia a :

class TInterface
{
  public:
      TPantalla *Crear_Pantalla(int x,int y,int bpp);
};

class TPantalla
{
    TPantalla();
public:
     virtual ~TPantalla();
     virtual Todas las otras funciones;
};


Habria que investigar la solución de ShAq que es por lejos la mas interesante ...
Los experimentos serian

proyecto pp.lib:
pp.cpp
class PP {
  int p
 public:
   pp();
   static int sgetp();
   int getp();
};
pp:pp() { p=sizeof(PP); };
int pp:sgetp() { return sizeof(PP); };
int pp:getp() { return p; };

proyecto nuevo
main.cpp
#pragma lib pp.lib
class PP {
 public:
  pp();
  static int sgetp();
  int getp();
};

void main(){
  printf("%d %d %d\n", sizeof(PP), PP::sgetp(), p.getp());
}
No tengo un compilador aca para probar ... pero incluso si todo esto resultara bien, no estoy seguro de que como andará en todo momento ( en debug en release, en otro compilador) ... la mayor pregunta es ¿dónde dice cuanta memoria se debe reservar?, ¿en el constructor? pues de ser así no habria problemas ... ahora con un PP p[3000]; ¿se seguiría manteniendo el sizeof adecuadamente? ¿En todos los compiladores esto anda?

Si alguien sabe algo ...
Saludos y gracias
Título: Cosas Ocultas En Una Lib
Publicado por: zupervaca en 05 de Octubre de 2005, 09:29:01 PM
Cita de: "zupervaca"en mi practica con librerias de c++ siempre hay una funcion global o que pertenece a otra clase que nos devuelve la clase creada solucionando el problema que mencionas, un ejemplo de ello se ve en direct3d, siempre que quieres crear un objeto com le pasas un puntero y el te crea el objeto, de esta forma el usuario tendra solo acceso a los miembros que pongas en el .h que le des, pero estaras creando correctamente el objeto ya que lo hace tu libreria, espero que se entienda lo que quiero decir ;)
aqui ya te daba la solucion que usa en estos casos
Título: Cosas Ocultas En Una Lib
Publicado por: senior wapo en 05 de Octubre de 2005, 10:23:42 PM
 Olvidate de lo que ha dicho Shaq. NO puedes borrar nada en la cabecera. Lo que te haces es una clase proxy que simplemente guarde un puntero a la clase que envuelve.

Si borras los datos miembro ¿ como vas a reservar espacio para ellos (new) si no sabes su tamaño real?
¿ Y si hay funciones virtuales y el compilador guarda el puntero a la vtable al final del objeto en lugar de al principio ? (Gcc anterior al 2.8 por ejemplo).
¿ Y si tienes funciones inline que acceden a datos publicos que an despues de los que has borrado ? El compilador del usuario pensará que el dato está al principio del objeto en lugar de 324 bytes más adelante.

Si le ha funcionado es porque el compilador no ha instanciado código inline que acceda a datos, y de haber clases virtuales, el puntero a la table lo metía al principio (VC++ o gcc de los de ahora). Y me supongo que no era una clase con polymorfismo, o peor, herencia multiple. Vamos, que ha sido más casualidad que otra cosa :)

Título: Cosas Ocultas En Una Lib
Publicado por: Pogacha en 05 de Octubre de 2005, 11:00:24 PM
 Eso sospechaba, pero estas seguro?

Nunca vi antes eso de la clase proxy, que ventaja tendria contra este sistema:

Lib:
class Verdadera : public Trucha
{
   int j, k;
 public:
   int x, y;
  Verdadera();
  ~Verdadera();
  MisFunciones();
};

Trucha *Crear_Trucha() { return new Verdadera; }


Usuario:
class Trucha {
public:
  virtual ~Trucha();
  virtual MisFunciones();
};

INPORTAR Trucha *Crear_Trucha();


Pregunto por ignorancia, que no se me malinterprete, escribo el codigo para poder expresar bien lo que quiero decir ... con clases virtuales trabajaba ya en dlls de esta manera pero supuse que para libs deberia haber algo mas sencillo...
Título: Cosas Ocultas En Una Lib
Publicado por: _Grey en 05 de Octubre de 2005, 11:27:59 PM
 
CitarNunca vi antes eso de la clase proxy, que ventaja tendria contra este sistema
...

Esto de las clases proxy es lo "habitual", es la solucion que encontraras en los libros de C++ que trater la ocultacion de codigo.

Que ventajas tiene en comparacion con una interface??
Eso ya depende de ti, si usas una interface necesitaras de funciones especiales para la creacion del objeto y la liberacion de este, ademas de la carga de las funciones virtuales. Con la clase proxy, el objeto seguira comportandose como un objeto, lo puedes crear normalmente y esperar que se destruya al final de la funcion sin mas, salvo de ser dinamico, y te salvas de la carga de funciones virtuales, puesto que solo haces una llamada al objeto real dentro de cada funcion, que con un inline es como si la pones en la llamada a la funcion de proxy.
Si te interesa un OBJETO, clase proxy.

Saludos.
Título: Cosas Ocultas En Una Lib
Publicado por: senior wapo en 05 de Octubre de 2005, 11:33:37 PM
 A menos que tengas respuestas para las preguntas (retóricas) que he puesto, pues si, estoy seguro :D

Lo que tu pones, usando polimorfismo, es otra forma de hacerlo Supongo que la más elegante en la mayoria de los casos ().

La idea es no borrar nada de la declaración de clase.
Título: Cosas Ocultas En Una Lib
Publicado por: Pogacha en 06 de Octubre de 2005, 09:21:06 PM
 Muchas gracias ...