3

メンバー関数がある場合。. .

MyClass::MyFunction()
{
    while(1)
    {
        //blah blah blah
    }
}

. . . そして、この関数のスレッドを作成しようとします。. .

CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)MyFunction, NULL, 0, NULL);

. . . (LPTREAD_START_ROUTINE)MyFunction が無効な型キャストであり、非静的メンバー関数のスレッドを作成できないというエラーが常に表示されます。

thisポインターを数回使用するため、非静的メンバー関数を使用する必要があるため、関数を静的にすることはできません。

非静的メンバー関数のスレッドを作成する簡単な方法はありますか?

(私は Visual Studio 2010、C++、MFC で作業しています)

4

3 に答える 3

4

おそらく「start()」関数を除いて、このすべての情報を非公開にする必要があります。オペレーティングシステムのスレッド開始のターゲットとしてクラスのプライベート静的メンバー関数を持ち、「start()」でスレッド開始メソッドにオブジェクトの「this」ポインターを渡し、それをオブジェクトの型にキャストし直します。次に、オブジェクト自体でプライベート メイン スレッド メソッドを呼び出す静的関数。静的関数はクラスのメンバーであるため、プライベート関数を使用できますが、そうでない場合は (フレンドにならずに) 使用できません。私はこれをコンパイル/テストしませんでしたが、アイデアは次のとおりです。

class MyObj {
private:
    void thread() {
            // this-> is valid here
    }

    static DWORD static_entry(LPVOID* param) {
        MyObj *myObj = (MyObj*)parm;
        myObj->thread();
        return 0;
    }

public:
    void start() {
        CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)static_entry, this, 0, NULL);
    }
};

警告: スレッドの実行中にオブジェクトを破棄しないでください。ミューテックスと同期するか、オブジェクトの破棄時にスレッドが結合されていることを確認する必要がある場合があります。start() の呼び出し元がオブジェクトを管理しなくなった場合は、thread() の最後で「これを削除」するか、static_entry の最後で myObj を削除することもできます。

于 2013-02-07T15:57:47.150 に答える
2

静的関数を作成する

static DWORD myFunctionCaller(LPVOID* param)  
{
  MyClass* myClass = static_cast<MyClass*>(param);
  myClass->MyFunction();
}

CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)myFunctionCaller, this, 0, NULL);

欠点は、いくつかのフローティング静的関数を取得できることですが、スコープを簡単に制限できるため、スレッドが多すぎるのを防ぐことができます。

于 2013-02-07T14:52:20.143 に答える
2

C ++メンバー関数は、クラスインスタンスなしでは呼び出すことができません。次のコードは私の提案の1つです。

MyClass * instance = ...; // valid instance.
CreateThread(NULL, 0, StartRoutine, instance, 0, NULL);

DWORD WINAPI StartRoutine(LPVOID ptr) {
  static_cast<MyClass*>(ptr)->MyFunction();
}

staticもう1つの提案は、キーワードを使用してメンバー関数を宣言することです。

class MyClass {
  ...
  static DWORD WINAPI MyFunction();
  ...
}

2番目のコードでは、MyFunctionクラス(非static)メンバー変数にアクセスできません。

于 2013-02-07T14:47:00.677 に答える