Usando thread de impulso e uma function de class não estática

Então eu fiz algumas pesquisas, e descobri que você pode criar um object boost :: thread e fazer com que ele comece com uma function de class não-estática usando “this” e boost :: bind etc. Realmente não faz muito sentido para mim e todos os exemplos que eu pude encontrar tiveram o object boost :: thread lançado dentro da mesma class que a function que estava começando, então isso poderia ser usado. Eu, no entanto, estou lançando o thread em uma class diferente, então eu estou com medo de usar “this”, eu estarei dizendo que o “this” é da class que estou criando o thread de, ao invés do que a function está em ( Eu provavelmente estou errado, eu preciso aprender mais sobre esse “esse” cara). Aqui está um exemplo da minha fonte que estou tendo o problema com.

ANNGUI.h

 class ANNGUI
 {
 privado:
     boost :: thread * GUIThread;
     Principal * GUIMain;
 público:
     // Cria a GUI inteira e todas as subpartes.
     int CreateGUI ();
 }

ANNGUI.cpp

 int ANNGUI :: CreateGUI ()
 {
         GUIMain = new Main ();
     GUIThread = new boost :: thread (GUIMain-> MainThreadFunc);
 };

Esta não é toda a fonte, mas eu acho que o meu problema está aqui em algum lugar, eu sei que tenho que lidar com o “isto” de alguma forma, mas não tenho certeza de como. Eu poderia usar uma function estática, mas eu realmente não queria tornar minhas variables ​​estáticas também. Obrigado.

Além disso, existe algum recurso muito bom para usar qualquer biblioteca de reforço? A documentação do site deles parece boa, mas acima da minha cabeça.

A palavra-chave this é usada com boost::bind quando o object de function que você está criando está vinculado a uma function de membro de object . As funções de membro não podem existir separadas das instâncias, portanto, ao criar um object functor a partir de uma function de membro com boost::bind , você precisa de um ponteiro para uma instância. É exatamente isso que a palavra this chave this realmente é. Se você usar a palavra this chave this em uma function de membro de uma class, o que você obtém é um ponteiro para a instância atual dessa class.

Se você chamasse bind de fora de uma function de membro da class, você poderia dizer algo como:

 int main() { Foo f; boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f)); } 

Aqui, estamos usando Foo :: some_function como nossa function de thread. Mas não podemos usar this porque estamos chamando bind de main . Mas a mesma coisa poderia ser conseguida usando this se nós chamamos bind de dentro de uma function membro de Foo, da seguinte forma:

 void Foo::func1() { boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this)); } 

Se uma function de membro é estática, ou é simplesmente uma function regular (não-membro), então você não precisa de um ponteiro de instância. Você apenas faria:

 boost::thread* thr = new boost::thread(some_regular_function); 

Como outros mencionaram, quando você deseja chamar um método de object em um novo segmento, você deve fornecer o endereço desse object. Mas você não precisa chamar boost::bind , você pode usar o construtor overload boost::thread sobrecarregado assim:

 GUIThread = new boost::thread(&Main::MainThreadFunc, GUIMain); 

Se o método estiver na mesma class, use this para obter o endereço da instância atual, por exemplo:

 t = new boost::thread(&myclass::compute, this); 

Se o método tiver parâmetros, você pode especificá-los após o segundo argumento, por exemplo:

 t = new boost::thread(&myclass::compute, this, p1, p2); 

boost :: bind é seu amigo (às vezes pode ter uma maneira difícil de mostrar isso)!

use GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));

e faça do seu MainThreadFunc um membro regular. Isso significa que você pode usar as variables ​​de instância diretamente, como faria normalmente.

Algo assim:

 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; }; 

Em casos como este, é útil pensar em funções de membro não-estático como funções livres que tomam this como primeiro parâmetro, por exemplo no seu caso void MainThreadFunc(Main* this) .

boost::thread aceita um functor nullary, então você tem que passar um functor null que contém uma referência à instância GUIMain e chama GUIMain->MainThreadFunc que, como explicado acima, seria algo como MainThreadFunc(GUIMain) .

Boost (e agora também C ++ com TR1) fornece ajudantes para criar tais functores, a saber boost::bind (ou alternativamente boost::lambda::bind ). A expressão boost::bind(f, arg1, arg2, ...) significa “retornar um functor nulo que chama f(arg1, arg2, ...) “.

Dito isto, você pode usar a seguinte expressão para criar o segmento:

 GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain)) 

Se o seu object é um functor, ou seja, tem um operator() , você pode passar uma instância dele para boost::thread . O operator() não precisa ser estático. Por exemplo:

 #include  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; }