Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Punteros A Funciones Miembro De Una Clase

Iniciado por Storm, 05 de Agosto de 2003, 02:31:51 PM

« anterior - próximo »

Storm

 Supongamos k tengo una clase con una funcion y un puntero a una funcion de ese tipo:


class MyClass
{
public:
   void Render();
   void (* OnRender)(void);
};


Al asginar a OnRender = Render; me da un fallo "cannot convert from 'void (__thiscall CModelo::*)(void)' to 'void (__cdecl *)(void)" todo logico, ya lo se. La cuestion es k no se como poder hacerlo ( si uso __thiscall en la definicion del puntero me dice que esta puesta para uso futuro), en fin, que si alguien sabe la respuesta a esta tonta pregunta gracias

tamat

 Yo tambien tengo interes, además está el problema de la instancia porque no es lo mismo el puntero a un miembro de la instancia A que de la B ya que ambas tienen diferentes atributos, como se especifica eso? O solo se puede hacer referencia a funciones estaticas?.
Yo ahora mismo todo lo que usa callbacks (sobretodo tema threading) lo tengo en C fuera de mi clase porque no se como incrustarlo dentro así que cualquier info relativa me vendrá bien.
Por un stratos menos tenso

samsaga2

 Cual es la razon de la funcion OnRender? Enviar un evento por cada frame que se renderize? Puedes usar funciones virtuales:


class IRender {
public:
   virtual void OnRender() = 0;
};

class MyClass: public IRender
public:
   void OnRender() {
       // pinta una bonita escena
   }
}

// Luego puedes hacer
// ...
IRender* render = (IRender*) my_class_instance;
render->OnRender();
// ...


Espero que sea lo que buscabas.

Storm

 Pues mi idea (k no se si se podra llevar a cabo) es tener un formato de modelo k incluya animacion por frames, animacion por eskeleto, estatico, frustum culling etc, lo que queria hacer es lo siguiente:
Leo la informacion del archivo y si es un modelo estatico pues hace que OnRender apunte a una funcion k solo renderice un frame( ya k solo habra uno), si es de animacion, pues k interpole y renderize, si es un mapa k haga fustrum, para tener todo en un formato, no se si me explico.

Una idea k se me ha ocurrido para hacer esto es:

class MyClass
{
public:
   static void Render1(MyClass *Mia);
   static void Render2(MyClass *Mia);
   void (*OnRender)(MyClass*);
};


Lo malo es k para llamarla habra k pasarle la clase a la k se llama y en las funciones de render pues habra k estar poniendo Mia-> todo el tiempo. Pero no se me ocurre nada mejor para eso.
Auque ahora k me lo dices samsaga2 pues estaria bien usar virtuales pero no se donde lei k relentizaba el codigo  :blink: aunque no lo se a ciencia cierta.

PD: Por algo Carmack usa solo C, digo yo.

tamat

 joer, eso de que relentizan el codigo... calculo que solo será un ciclo de CPU por llamada a funcion virtual ya que la dirección de la funcion la tiene que obtener de una tabla de punteros a función pero tratandose de un mensaje como ese no creo que te venga de un ciclo, otra cosa es que tu clase point3D utilice virtuales, ahí si que habría problemas, pero para mensajes y demás no hay ningun problema.

Tienes que aprender a separar lo que se ejecuta de manera exponencial (colisiones, calculos con vertices, IA, LoD) y lo que se ejecuta de manera eventual (cuando el raton se pulsa, cuando se pide pintar un frame, cuando empieza un sonido) ya que lo segundo por muy optimizado que lo tengas no notaras la diferencia mientras que en lo primero cada milisegundo que saques supondrá muchos fps más por segundo.

Sería como intentar optimizar la función de salir del juego... quién notaria la diferencia?
Por un stratos menos tenso

Zaelsius

 Si quieres crear diferentes objetos que parten de una clase base común, tal vez te resulte cómodo crear una clase "factoría", hay un tuto en Planet Iso
(ver final del tuto).

El diseño del código de Carmack no es el mejor ejemplo a seguir, precisamente.   :ph34r:

Sobre lo que dice tamat, le doy la razón. No os perdais el próximo nº de edevi! ;)

Juan Mellado

 Storm, yo también creo que sería mejor funciones virtuales. Sólo quería comentar que los punteros a miembros de una clase tienen esta pinta:

class MyClass
{
public:
  void Render();
  void (MyClass::* OnRender)(void);

  MyClass() {OnRender = &MyClass::Render;}
};

Busca "Pointers to Class Members" si estás interesado en el tema.

tamat, en este thread de Flipcode:
http://www.flipcode.com/cgi-bin/msg.cgi?sh...m=general&id=-1
hay una discusión de como usar miembros estáticos para las CALLBACK (de ventanas de Windows)

Saludos

Storm

 Pensandolo voy a usar los dos metodos, es decir, derivas la clase de una clase base y usar puneros a funciones. El uso de punteros a funciones lo quiero para un renderizado mas rapido de los objetos, por ejemplo, si kiero usar sombras y luz pues apunto a esa funcion , si no apunto a otra, asi con lo basico. Y asi evito los if(g_bSombras), y poder cambiar el metodo Render en tiempo de ejecucion( que es para lo que lo kiero de verdad ). Lo de los metodos virtuales lo usare para renderizar varios objetos con diferente estructura y por lo tanto diferente forma de renderizarse. Incluire tambien punteros a funciones de otro tipo como IA, etc.

Gracias a todos por vuestra ayuda

Storm

 Juan Mellado: He probado tu metodo y no da errores al compilar, pero si al llamar al puntero: "term does not evaluate to a function", he estado mirando por ahi lo de los punteros a miembros de clases y creo k deberia llamarse al puntero mediante
(Mia.*OnRender)(); pero no se puede  (nooo) , A ver si puedes sacarme de esta duda please, dejo el codigo:


class MyClass //: public IRender
{
public:
 void Render();
 void (MyClass::*OnRender) ();

 MyClass() {OnRender = &MyClass::Render;} // No da fallos si es solo MyClass::Render
            //pero como no se como va no toco
};

// Para llamar al puntero
MyClass Mia;
Mia.OnRender(); // Curioso error
// O si no com he visto googleando

(Mia.*OnRender)(); // Pero tampoco va


Lo que busque del google es:
http://www.lnf.infn.it/computing/doc/aixcx...ef/rnpt2mem.htm
http://www.clipx.net/ng/zc_ref/ng6a945.php

(nooo)  (nooo)  (nooo)

PD: Creia que iva a ser una pregunta tonta con su facil respuesta, pero veo que se ha saldio de 'principiantes'  ;)  

Storm

 Vale, ok, ya esta todo!!!!  (ole)

bueno, se llama mediante:

(Mia.*(Mia.OnRender))();

kisiera volver a agradeceros todo  :D  :D  :D

PD: Los edit de los post caducan en nada


ethernet

 c++ ya da un sistema automatico para controlar eso (herencia virtual), dejemos las cosas cutres y poco elegantes para los que programan en c. Yo estoy con samgaga2, prefiero un interface como dios manda antes de un puntero a funcion.

Por otra parte puede resultar interesante en este caso el pattern Functor.


saludos

ethernet

 con respecto a el tutorial de plateniso : http://www.planetiso.com/patrones.html
mas concretamente :



BaseClass* ClassFactory::CreateObject( int id)
{
   BaseClass* pClass = 0;

   switch( id )
   {
       case 1:
           pClass = new Class1;
           break;

       case 2:
           pClass = new Class2;
           break;

       case 3:
           pClass = new Class3;
           break;

       default:
           assert("Error! Se ha pasado una ID incorrecta a la clase factory!");

   };

   //aqui podemos poner algo de codigo comun para la inicializacion
   pClass -> Init();
   return pClass;
}


Te recomiendo que no hagas ni puto caso a ese codigo XD. Si quieres una factory de verdad, en el q se puedan registrar tipos etc mirate el siguiente cotd de flipcode: http://www.flipcode.com/cgi-bin/msg.cgi?sh...orum=cotd&id=-1 (el thread esta muy interesante tb) concretamente la parte de la factory, olvida lo demas.

Por cierto, sin animo de joder a nadie, pero ese tutorial ya lo habia visto yo en alguna parte (http://www.geocities.com/cordayuk/Direct3D/comodiosmanda/diseno.htm) supongo que no se tratara de una copia si no una publicacion de un tutorial con el permiso del autor.

saludos

Zaelsius

 Yo he puesto el link a ese tuto pq es el último que recordaba haber visto del tema...lo encontré navegando el otro dia en planet-iso a raiz del post de Helius. :ph34r:  

Storm

 Pues si, estoy viendo que las virtuales es lo mejor. Como hariais vosotros por ejemplo un sistema de particulas en el k la fisica de estas pueda variar dentro de unas cuantas predefinidas, explosiones, agua,etc. Mi idea para eso era usar punteros a funciones miembro para poder cambiarlo en tiempo de ejecucion sin tener k poner los switch. De todos modos por ahora voy a poner una interfaz para los objetos k necesiten renderizarse con los metodos basicos.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.