2011-01-12 6 views
5

Como dice el título. El siguiente es mi código esqueleto.ejecutar los hilos de la función de miembro de clase en C++

class CLASS 
{ 
public: 
    void A(); 
private: 
    DWORD WINAPI B(LPVOID); 
}; 

void CLASS::A() 
{ 
    DWORD (WINAPI CLASS::*thread)(LPVOID) = &CLASS::B; 
    ... 
    CreateThread(NULL, 0, thread, &arg, 0, NULL); 
    ... 
} 

la función B necesita las variables de miembro de CLASS.
Pero tengo un código de error cuando compilé esto.
Es "no se puede convertir el argumento 3 de 'DWORD (__stdcall CLASS :: *) (LPVOID)' a 'LPTHREAD_START_ROUTINE'" o algo por el estilo.
No sé si es lo mismo en el entorno inglés.

¿Alguien puede ayudar, por favor?

Respuesta

3

Tienes que hacer que la función de miembro static.

El problema aquí es que cada función de miembro no estática tiene un parámetro implícito this y eso es lo que el compilador intenta decirle: su función de miembro nin-static tiene una firma diferente a la que esperaba.

Ver también this answer to a closely related question.

+3

Y delante de las salidas OP obtener cualquier idea inteligente: los punteros de función de miembro de clase no estáticos son * extraños *. No solo las convenciones de llamada son diferentes de un simple 'func (classname * this, ...)', la _pointer representation_ es rara - en algunos casos, los punteros de función de miembro de clase pueden llegar a ser 2 veces el tamaño de un puntero de función normal, entonces ni siquiera pienses en forzar el elenco :) – bdonlan

10

¡Tiene que definir su función de devolución de llamada como función static si es función de miembro!


Mejor diseño: ¡defina una clase reutilizable!

Desde mi previous answer: (con pequeñas modificaciones)

Aún mejor sería definir una reutilizable clase con la función virtual pura run() a ser implementado por los derivados de rosca clases. Aquí es cómo debe diseñarse:

//runnable is reusable class. All thread classes must derive from it! 
class runnable 
{ 
public: 
    virtual ~runnable() {} 
    static DWORD WINAPI run_thread(LPVOID args) 
    { 
     runnable *prunnable = static_cast<runnable*>(args); 
     return prunnable->run(); 
    } 
protected: 
    virtual DWORD run() = 0; //derived class must implement this! 
}; 

class Thread : public runnable //derived from runnable! 
{ 
public: 
    void newthread() 
    { 
     CreateThread(NULL, 0, &runnable::run_thread, this, 0, NULL); 
    } 
protected: 
    DWORD run() //implementing the virtual function! 
    { 
     /*.....your thread execution code.....*/ 
    } 
} 
+0

Usaría una plantilla, en lugar de una herencia en tiempo de ejecución. Pero la idea general es correcta. – Puppy

+0

@DeadMG: ¿te refieres a CRTP? – Nawaz

+0

+1, pero protegería el método 'run'. –

11

En serio, el uso std :: hilo (o boost :: hilo si el compilador no admite todavía):

class CLASS 
{ 
public: 
    void A(); 
private: 
    void B(your args go here); 
}; 

void CLASS::A() 
{ 
    boost::thread(&CLASS::B, this, your args go here); 
} 
+2

+1. Sí, definitivamente vaya con std ::/boost :: thread. Además, ni siquiera necesitas bind: 'boost :: thread t (& CLASS :: B, esto, tus argumentos, si alguno va aquí);'. Tan sencillo como eso. – usta

+0

@usta: ¡gracias! fijo. – ybungalobill

Cuestiones relacionadas