だから私はいくつかの研究を行い、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); };
これがすべてのソースではありませんが、私の問題はここのどこかにあると思います。どうにかして「これ」に対処しなければならないことは知っていますが、どうすればよいかわかりません。静的関数を使用できますが、変数も静的にしたくありませんでした。ありがとう。
また、ブーストライブラリを使用するための非常に優れたリソースはありますか?彼らのウェブサイトのドキュメントは良いように思えますが、私の頭上です。
作成している関数オブジェクトがオブジェクトメンバー関数にバインドされている場合、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);
他の人が述べたように、新しいスレッドでオブジェクトメソッドを呼び出すには、そのオブジェクトのアドレスを指定する必要があります。ただし、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);
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;
};
このような場合、非静的メンバー関数を、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))
_
オブジェクトがファンクター、つまり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;
}
_