Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   constructor con parámetros que son funciones (https://www.clubdelphi.com/foros/showthread.php?t=73261)

robinsongm 12-04-2011 01:03:52

constructor con parámetros que son funciones
 
Buenas!
Tengo la siguiente estructura de clases (obviamente es un esquema para representar la situación, no es mi código original):
Código:

class  A
{
public:
  A(void (*vEvent) (A *, char)): event_A(vEvent) {};
  ~A() {};

  void (*publicEvent_A) (A *);
private:
  void (*event_A) (A *, char);
 
  void myProcedure ()
  {
      event_A (this, 'x');
  }
};

class B
{
public:
  B():
    myA(event_B)
  {
    /*  myA = new A(event_B); */
    myA->publicEvent_A = myProcedure_B;
  };

  ~B();
private:
  A *myA;
 
  void event_B (A *p1, char p2)
  {
    // hago cosassss...
  };

  void myProcedure_B (A *sender)
  {
    sender = sender; //do anything
  };

};

El caso es que al compilar tengo un error como este (en las líneas que he resaltado en el código):
main.cpp:20: error: argument of type ‘void (B:: )(A*, char)’ does not match ‘A*’
main.cpp:23: error: argument of type ‘void (B:: )(A*)’ does not match ‘void (*)(A*)’

Entiendo lo que quiere decir, pero si por ejemplo solo declaro la clase A y en el main.cpp escribo:
Código:

void eventoA (A *sender, char p)
{
  // codigo
}

void otroEventoA (A* sender)
{
  //  codigo
}

int main ()
{
    A *myA = new A(eventoA);
    myA->publicEventA = otroEventoA;
}

Esto anterior Sí funciona, si no existiese la clase B tal cual la tengo implementada.

¿Alguien puede decirme cómo corregir el error inicial (con ambas clases implementadas según el primer código)?
Tampoco deseo cambiar los niveles de seguridad mostrados, lo que está en public y private debe permanecer tal cual.

Gracias de antemano!!

Ñuño Martínez 12-04-2011 14:38:03

El problema es que el constructor espera un puntero a una función, sin embargo tú le estás pasando un método. No es lo mismo ya que los métodos están asociados a objetos, mientras que con las funciones no es así.

¿La solución? Pues no estoy seguro porque hace eones que no programo en C++ (ni ganas tengo) pero en ObjectPascal es posible pasar métodos como parámetros y luego asociarlos a objetos. No recuerdo si con C++ podía hacerse, o si hay otra solución, pero no me apetece pensar más.

_cero_ 13-04-2011 10:09:39

mmm me he liado tanto:confused::confused::confused:, con las simples llamadas a este que llama a este otro que no se si termine con más dudas que respuestas, pero la cosa creo que va por enviar algo que no existe, es decir en la creación de B aún no hay ninguna dirección que apunte a event_B (esta es la única explicación a la que doy fe), por ende la solución sería crear punteros del tipo al método que usas, pero que estén por encima de B o que se creen antes, después le asignas la función y así ya jala. La cuestión es que cosas ases en event_B, algo así:D.

Código:

class A
{
public:
    A( void( * vEvent )( A* , char ) ) : event_A( vEvent ){ };
    ~A( ){ };
    void( *publicEvent_A )( A* );

private:
    void( *event_A )( A*, char );
    void myProcedure( )
    {
        event_A( this, 'x' );
    }
};

typedef void( *Fun )( A * p1, char ca );
typedef void( *Fun2 )( A * a );
Fun aa;
Fun2 bb;

class B
{
public:
    B( )
    {
        myA = new A( aa );
        myA->publicEvent_A = bb;
    };
    ~B( );

private:
    A* myA;
    void myProcedure_B( A* sender )
    {
        sender = sender;
    };
};

En fin me lie así que este comentario también es un lio, ahora incluso no distingo la diferencia entre puntero o instancia jaja.

Pd. Estimado Ñuño Martínez desde la ignorancia pregunto, función no es lo mismo que método? Ambos tienen parámetros variables y retornos variables, siendo la única diferencia el paradigma de programación (estructurada u orientada a objetos, es decir solo palabras no funcionalidad), porque hasta donde yo he programado da lo mismo pasar una función X a un OnClick X.

Pd2. Sería interesante que alguien resolviera el hilo y dijera que está pasando ya que sí que no me funciona pero no le encuentro falla lógica.

Ñuño Martínez 13-04-2011 10:26:29

Cita:

Empezado por _cero_ (Mensaje 396851)
Pd. Estimado Ñuño Martínez desde la ignorancia pregunto, función no es lo mismo que método? Ambos tienen parámetros variables y retornos variables, siendo la única diferencia el paradigma de programación (estructurada u orientada a objetos, es decir solo palabras no funcionalidad), porque hasta donde yo he programado da lo mismo pasar una función X a un OnClick X.

Te equivocas cuando dices que la única diferencia son "solo palabras no funcionalidad". Como ya he dicho, los métodos han de estar asociados a un objeto, por lo que sí hay una diferencia importantísima.

Según la definición más pura de la POO, los métodos implementan la respuesta a los mensajes que se envían a un objeto. La confusión quizá provenga en la forma en la que C++, Object Pascal y similares implementan los métodos, que lo hacen como "llamadas a función con parámetro implícito", this en un caso y SELF en el otro. Sin embargo lenguajes como Small-Talk u Objective C los métodos no se implementan como si fueran funciones por lo que la diferencia está más clara. Es más, en Objective C la nomenclatura es diferente para funciones y para métodos, mientras que en Small-Talk ni siquiera existen las funciones.

Para que veas, te pongo un ejemplo de método en Objective C:
Código:

- (int)method:(int)i
{
    return [self square_root:i];
}

Como ves es parecido pero no igual a una función, mientras que las funciones en este lenguaje son idénticas a las de C. De esta forma a un programador le resultará muy sencillo saber si lo que está viendo es o no un método.

Para que lo veas más claro, cuando escribimos esto en C++:
Código:

  UnObjeto.Metodo (Parametro, OtroParametro);
  ElObjeto->Metodo (Parametro, OtroParametro);

el compilador lo maneja como si fuera esto:
Código:

  ((*(UnObjeto.Metodo)) (&UnObjeto, Parametro, OtroParametro));
  ((*(ElObjeto->Metodo)) (ElObjeto, Parametro, OtroParametro));


_cero_ 13-04-2011 10:41:53

:eek::eek::eek: llevo tanto tiempo programando en un solo lenguaje que a veces olvido que el mundo no está escrito solo en C++. Gracias por despejarme ahora entiendo más que un método es algo así como la representación de los mensajes enviados y recibidos a un objeto, y una función no tienen nada que ver con esto a pesar de que reciban o regresen punteros de objetos (o eso capte en este instante, en cualquier caso nunca está de más pasarme por google a redefinir algunos de mis conceptos:o), otra vez gracias:D.


La franja horaria es GMT +2. Ahora son las 19:07:35.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi