c++ - saber - que significa de clase c2
Usar hilo de refuerzo y una función de clase no estática (5)
Como otros mencionaron, cuando desea llamar a un método de objeto en un nuevo hilo, debe proporcionar la dirección de ese objeto. Pero no necesitas llamar a boost::bind
, puedes usar el sobrecargado boost::thread
constructor de esta manera:
GUIThread = new boost::thread(&Main::MainThreadFunc, GUIMain);
Si el método está en la misma clase, lo usa para obtener la dirección de la instancia actual, por ejemplo:
t = new boost::thread(&myclass::compute, this);
Si el método tiene parámetros, puede especificarlos después del segundo argumento, por ejemplo:
t = new boost::thread(&myclass::compute, this, p1, p2);
Así que investigué y descubrí que puedes crear un objeto boost :: thread y hacer que comience con una función de clase no estática usando "this" y boost :: bind etc. Realmente no tiene mucho sentido para mí y todos los ejemplos que pude encontrar tenían el objeto boost :: thread lanzado dentro de la misma clase que la función con la que estaba empezando, por lo que podría usarse. Sin embargo, estoy lanzando el hilo en una clase diferente, así que me temo que al usar "esto", diré que "esto" es de la clase de la que estoy creando el hilo, en lugar de aquella en la que está la función ( Probablemente estoy equivocado, necesito aprender más sobre este "este" chico). Aquí hay un ejemplo de mi fuente con la que estoy teniendo el problema.
ANNGUI.h
class ANNGUI { private: boost::thread *GUIThread; Main *GUIMain; public: // Creates the entire GUI and all sub-parts. int CreateGUI(); }
ANNGUI.cpp
int ANNGUI::CreateGUI() { GUIMain = new Main(); GUIThread = new boost::thread(GUIMain->MainThreadFunc); };
Esta no es toda la fuente, pero creo que mi problema está aquí en alguna parte, sé que tengo que lidiar con el "esto" de alguna manera, pero no estoy seguro de cómo. Podría usar una función estática, pero tampoco quería que mis variables estuvieran estáticas. Gracias.
Además, ¿hay algún recurso muy bueno para usar cualquier biblioteca de impulso? La documentación de su sitio web parece buena, pero por encima de mi cabeza.
En casos como este, es útil pensar en funciones miembro no estáticas como funciones libres que toman this
como primer parámetro, por ejemplo en su caso void MainThreadFunc(Main* this)
.
boost::thread
acepta un functor nullary, por lo que debe pasarle un functor nullary que contiene una referencia a la instancia GUIMain
y llama a GUIMain->MainThreadFunc
que, visto como he explicado anteriormente, sería algo así como MainThreadFunc(GUIMain)
.
Boost (y ahora también C ++ con TR1) proporciona ayudantes para crear dichos funtores, concretamente boost::bind
(o alternativamente boost::lambda::bind
). La expresión boost::bind(f, arg1, arg2, ...)
significa "return a nullary functor que llama a f(arg1, arg2, ...)
".
Dicho esto, puede usar la siguiente expresión para crear el hilo:
GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain))
Si su objeto es un funtor, es decir, tiene un operator()
, puede pasar una instancia de él para boost::thread
. El operator()
no necesita ser estático. Por ejemplo:
#include <boost/thread.hpp>
struct th {
void operator()();
};
void th::operator()()
{
for (;;) {
// stuff
}
}
int main()
{
th t;
boost::thread my_thread( t ); // takes a copy of t !
my_thread.join(); // blocks
return 0;
}
boost :: bind es tu amigo (¡a veces puede tener una forma aproximada de mostrarlo)!
use GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));
y luego haga que su MainThreadFunc sea un miembro regular. Eso significa que puede usar las variables de instancia directamente como lo haría normalmente.
Algo como esto:
class GUIMain {
public:
GUIMain() : m_Member(42) {}
void MainThreadFunc() {
// use all members as you would normally do
std::cout << m_Member << std::endl;
}
private:
int m_Member;
};
La palabra clave this
se usa con boost::bind
cuando el objeto de función que está creando está vinculado a una función de miembro de objeto . Las funciones miembro no pueden existir aparte de las instancias, por lo que cuando se crea un objeto functor a partir de una función miembro con boost::bind
, necesita un puntero a una instancia. Eso es exactamente lo que es realmente this
palabra clave. Si usa la palabra clave this
dentro de una función miembro de una clase, lo que obtiene es un puntero a la instancia actual de esa clase.
Si llamaras a bind
desde fuera de una función de miembro de clase, podrías decir algo como:
int main()
{
Foo f;
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f));
}
Aquí, estamos utilizando Foo :: some_function como nuestra función de hilo. Pero no podemos usar this
porque estamos llamando bind
desde main
. Pero lo mismo podría lograrse usando this
si llamamos bind
desde dentro de una función miembro de Foo, de esta manera:
void Foo::func1()
{
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this));
}
Si una función miembro es estática, o simplemente es una función normal (no miembro), entonces no necesita un puntero de instancia en absoluto. Solo lo harías:
boost::thread* thr = new boost::thread(some_regular_function);