web-dev-qa-db-ja.com

ブーストスレッドと非静的クラス関数の使用

だから私はいくつかの研究を行い、boost :: threadオブジェクトを作成し、「this」とboost :: bindなどを使用して非静的クラス関数で開始できることを発見しました。それは実際にはあまり意味がありません私と私が見つけたすべての例では、boost :: threadオブジェクトが、それが使用できるように、それが開始されていた関数と同じクラス内で起動されました。しかし、私は別のクラスでスレッドを起動しているので、「this」を使用することを恐れています。「this」は、関数が属するクラスではなく、スレッドを作成しているクラスからのものであると言います私はおそらく間違っている、私はこの「この」男についてもっと学ぶ必要がある。ここに私が問題を抱えている私のソースの例があります。

ANNGUI.h

 class ANNGUI 
 {
 private:
 boost :: thread * GUIThread; 
 Main * GUIMain; 
 public:
 // GUI全体とすべてのサブパーツを作成します。
 int CreateGUI(); 
} 

ANNGUI.cpp

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

これがすべてのソースではありませんが、私の問題はここのどこかにあると思います。どうにかして「これ」に対処しなければならないことは知っていますが、どうすればよいかわかりません。静的関数を使用できますが、変数も静的にしたくありませんでした。ありがとう。

また、ブーストライブラリを使用するための非常に優れたリソースはありますか?彼らのウェブサイトのドキュメントは良いように思えますが、私の頭上です。

44
contrapsych

作成している関数オブジェクトがオブジェクトメンバー関数にバインドされている場合、thisキーワードはboost::bindと共に使用されます。メンバー関数はインスタンスとは別に存在できないため、boost::bindを使用してメンバー関数からファンクターオブジェクトを作成する場合、インスタンスへのポインターが必要です。これは、thisキーワードが実際に何であるかです。クラスのメンバー関数内でthisキーワードを使用すると、そのクラスの現在のインスタンスへのポインターが取得されます。

outsideクラスメンバー関数からbindを呼び出す場合、次のように言うことができます。

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

ここでは、スレッド関数としてFoo :: some_functionを使用しています。ただし、thisからbindを呼び出しているため、mainは使用できません。ただし、Fooのメンバー関数内からthisを呼び出した場合、bindを使用して同じことを実現できます。

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

メンバー関数が静的であるか、単に通常の(非メンバー)関数である場合、インスタンスポインターはまったく必要ありません。あなたはただやるでしょう:

boost::thread* thr = new boost::thread(some_regular_function);
83
Charles Salvia

他の人が述べたように、新しいスレッドでオブジェクトメソッドを呼び出すには、そのオブジェクトのアドレスを指定する必要があります。ただし、boost::bindを呼び出す必要はありません。オーバーロードされたboost::threadコンストラクターは次のように使用できます。

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

メソッドが同じクラスにある場合、thisを使用して現在のインスタンスのアドレスを取得します。例:

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

メソッドにパラメーターがある場合、2番目の引数の後にパラメーターを指定できます。例:

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

boost :: bindはあなたの友達です(ただし、大まかな方法​​で表示することもできます)!

GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));を使用します

そして、MainThreadFuncを通常のメンバーにします。つまり、通常どおりインスタンス変数を直接使用できます。

このようなもの:

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

このような場合、非静的メンバー関数を、thisを最初のパラメーターとして使用するフリー関数と考えると便利です。たとえば、void MainThreadFunc(Main* this)の場合です。

_boost::thread_はnullaryファンクタを受け入れるため、インスタンスGUIMainへの参照を含むnullaryファンクタを渡す必要があり、上記で説明したように_GUIMain->MainThreadFunc_を呼び出します。 MainThreadFunc(GUIMain)など。

Boost(および今ではTR1を備えたC++)は、そのようなファンクター、つまり_boost::bind_(または_boost::lambda::bind_)を作成するヘルパーを提供します。式boost::bind(f, arg1, arg2, ...)は、「f(arg1, arg2, ...)を呼び出すヌルファンクタを返す」ことを意味します。

ただし、次の式を使用してスレッドを作成できます。

_GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain))
_
3

オブジェクトがファンクター、つまりoperator()を持っている場合、そのインスタンスを_boost::thread_に渡すことができます。 operator()は静的である必要はありません。例えば:

_#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;
}
_
1
Bulletmagnet