recibir - ¿Es posible usar la señal dentro de una clase de C++?
como aumentar la señal wifi de mi celular (5)
Para pasar un puntero a un método, debe ser un método estático y debe especificar el nombre de la clase.
Prueba esto:
class myClass {
void myFunction ()
{
signal(SIGIO, myClass::myHandler);
}
static void myHandler (int signum)
{
// blabla
}
};
Y también debe leer el enlace proporcionado por Baget, el párrafo 33.2 en las preguntas frecuentes de C ++ .
Estoy haciendo algo como esto:
#include <signal.h>
class myClass {
public:
void myFunction ()
{
signal(SIGIO,myHandler);
}
void myHandler (int signum)
{
/**
* Handling code
*/
}
}
Estoy trabajando en Ubuntu, usando gcc.
Pero no compilará. Se queja con:
error: el argumento con tipo
void (MyClass::)(int)
no concuerda convoid (*) (int)
¿Alguna pista? ¿O tal vez es solo que no puedo usar una señal dentro de las clases? ¿Las señales solo están permitidas en C?
El mensaje de error es una traducción aproximada porque mi compilador no está en inglés.
El segundo parámetro de señal debe ser un puntero a una función que acepte un vacío int y return. Lo que está pasando para señalizar es un puntero a una función miembro que acepta un vacío int y return (su tipo es void (myClass::*)(int)
). Puedo ver tres posibilidades para superar este problema:
1 - Tu método myHandler
puede ser estático: esto es genial, myHandler
estático
class myClass
{
public:
void myFunction ()
{
signal(SIGIO, myClass::myHandler);
}
static void myHandler (int signum)
{
// handling code
}
};
2 - Su método no debe ser estático: si planea usar la señal con una sola instancia, puede crear un objeto estático privado y escribir un método estático que simplemente llame al método en este objeto. Algo a lo largo de las líneas de
class myClass
{
public:
void myFunction ()
{
signal(SIGIO, myClass::static_myHandler);
}
void myHandler (int signum)
{
// handling code
}
static void static_myHandler(int signum)
{
instance.myHandler(signum);
}
private:
static myClass instance;
};
3 - Sin embargo, si planea usar la señal con múltiples instancias, las cosas se volverán más complicadas. Quizás una solución sea almacenar cada instancia que desee manipular en un vector estático e invocar el método en cada una de ellas:
class myClass
{
public:
void myFunction () // registers a handler
{
instances.push_back(this);
}
void myHandler (int signum)
{
// handling code
}
static void callHandlers (int signum) // calls the handlers
{
std::for_each(instances.begin(),
instances.end(),
std::bind2nd(std::mem_fun(&myClass::myHandler), signum));
}
private:
static std::vector<myClass *> instances;
};
y en alguna parte, haz una sola llamada a
signal(SIGIO, myClass::callHandlers);
Pero creo que si terminas usando la última solución, probablemente deberías pensar en cambiar tu diseño de manejo :-)!
En realidad, los manejadores de señales de C ++ no tienen permitido usar ninguna instalación que no esté presente tanto en C como en C ++ (excepto que en C ++ 11 pueden usar átomos), y se requiere que usen enlaces C. Citando el borrador n. ° 3242 de C ++ 11 sección 18.10 "Otro soporte de tiempo de ejecución" [support.runtime] (párrafo 8),
El subconjunto común de los lenguajes C y C ++ consiste en todas las declaraciones, definiciones y expresiones que pueden aparecer en un programa C ++ bien formado y también en un programa C conforme. Una POF ("función vieja simple") es una función que utiliza solo características de este subconjunto común y que no utiliza directa o indirectamente ninguna función que no sea POF, excepto que puede usar funciones definidas en la cláusula 29 que no son funciones miembro Todos los manejadores de señal tendrán un enlace C. Un POF que podría usarse como manejador de señal en un programa C conforme no produce un comportamiento indefinido cuando se usa como manejador de señal en un programa C ++. El comportamiento de cualquier otra función utilizada como manejador de señal en un programa C ++ está definido por la implementación.
(Cláusula 29 es la de atómica).
#include <signal.h>
class myClass {
private:
static myClass* me;
public:
myClass(){ me=this; }
void myFunction (){
signal(SIGIO,myClass::myHandler);
}
void my_method(){ }
static void myHandler (int signum){
me->my_method();
}
}
Lea esta sección siguiente (33.2):