0

これが可能かどうかはわかりませんが、WinAPI を使用してスレッドを作成するための抽象クラスを作成するという考えがあります。このクラスは、スレッドで実行する関数を定義するクラスによって継承されます。

私は2つのクラスを持っています:

class XYZ{
//...

class ABC: public XYZ{
//...

そして、私は構造を持っています

ABC::ABC()
{
    addThread(this,1);
}

addThread は XYZ クラス内で定義されています。

void addThread(void* self, int a)
{
    DWORD ThreadID;
    THREAD_DATA *threadData;
    threadData->self = self;
    threadData->thread_id = a;
    CreateThread(NULL, 0, createThread, threadData, 0, &ThreadID);
}

ご覧のとおり、スーパークラスのオブジェクトとスレッドの数の 2 つのフィールドを含む構造体を作成しています (メソッドがどのデータを使用するかを知ることができるようにするため)。

構造は次のようになります。

typedef struct _THREAD_DATA {
void*       self;
int     thread_id;
} THREAD_DATA;

XYZ クラスの静的メソッドの createThread:

static DWORD WINAPI createThread(void* _threadData)
{
    THREAD_DATA* threadData = (THREAD_DATA*) _threadData;
    return threadData->self->execute(threadData->thread_id);
}

そして、ここがすべてがうまくいかない場所です。私の VSC++ 2010 では、静的メソッド本体の 2 行目の最初の単語「threadDataself」に下線が引かれています。コンパイル後、エラーが発生します:

'->execute' の左側は、class/struct/union/generic 型を指している必要があります

修正方法がわかりません。これらのリンクを使用してこのコードを書きました: http://goo.gl/7VYC3 & http://goo.gl/ETfe7

execute メソッドは、XYZ クラスで次のように宣言されます。

virtual DWORD execute(int i);

そして、ABC クラスで次のように定義されます。

DWORD ABC::execute(int i){
//...

誰でも私を助けてもらえますか?これを機能させるためのヒントをいただければ幸いです。

4

2 に答える 2

2

「self」は void ポインターとして定義されており、存在しない「execute」メソッドを呼び出そうとしています。self の型を「execute」メソッドを含む基本クラスに変更する必要があります。

このような:

typedef struct _THREAD_DATA {
    XYZ*       self;
    int     thread_id;
} THREAD_DATA;

このように、オーバーライドされたメソッドをポリモーフィックに呼び出そうとする場合は、メソッドを呼び出すオブジェクトの型が基本クラスの型であることを確認する必要があります。void ポインタは使用できません。

于 2012-10-23T21:34:32.240 に答える
1

修正すべき明らかなエラーの 1 つ:

THREAD_DATA *threadData;
threadData->self = self;
threadData->thread_id = a;

ここで、threadData は値が割り当てられていないポインターであり、is を有効なポインターとして使用します。に変更する必要があります

THREAD_DATA *threadData = new THREAD_DATA();

そしてどういうわけかその寿命を管理します。最後にスレッド関数内で削除します。

于 2012-10-23T21:58:12.473 に答える