0

クラス Foo では、Foo オブジェクトへのポインターを含む構造体 S であるクラス メンバーが必要です。

フー。

Struct S{
    ...
    Foo *ptrToFoo
}

class Foo{ 
    Foo();
    ~Foo();
    ...
    S sname;
};

sname の定義には、まだ確認されていないオブジェクトへのポインターが含まれているため、これは明らかに失敗します。

私が持っている解決策は、S 専用のオブジェクトを (ヘッダー ファイルで) 作成し、前方宣言を使用することです。

class Foo;
class S{
    Foo *ptrtoFoo;
    ...
}

フー。

// can use S as an object as a data member in Foo

これは私には本当にずさんなようです。これを行うより良い方法はありますか?S はメソッドを持たないため、それ自身のオブジェクトを「保証」しません; 構造体でも問題ありません。

理由を気にせず、ただ助けたいだけの場合は、残りをスキップしてください. 「これは私には悪いデザインのように思える!」と考えている場合は、読み進めてください。

私がこれを行っている理由は、pThreads_create が非静的クラス メンバー関数をパラメーターとして使用しないためです。一般的な解決策 (多くのスタック オーバーフローの投稿) が指摘しているように、必要な実際の関数を呼び出す静的メンバー関数を作成し、次のように呼び出し元オブジェクトを渡すことです。

void *Foo::callerHelper(void *arg)
{
    //http://stackoverflow.com/questions/7820653/pthread-create-parameter-function-pointer
    //http://stackoverflow.com/questions/86046/best-way-to-start-a-thread-as-a-member-of-a-c-class
    Foo *ptr = (Foo *)(arg);
    ptr->RealFnctnToCall();
    return 0;
}

...
pthread_create(&threads[id], NULL, &Foo::callerHelper, this)

ただし、これだけでなく、他の引数も渡す必要があります。私の「S」オブジェクトは、パラメーターのペイロードを表します。これへのポインターと、「RealFnctnToCall」に必要な実際のパラメーターが含まれています

S package;
S.FooPtr = this;
S.intINeed = ...
... 
//recast S as (void *)

そして、する

pthread_create(&threads[id], NULL, &Foo::callerHelper, S)
// in callerHelper, depackage S and get everything I want. 

上記の私の実際の質問に対するずさんな方法がない限り、この部分の解決策に満足しています。

4

2 に答える 2

1

Foo既存のコードで直接前方宣言するのはどうですか? これが標準的な C++ の方法です。

class Foo;
Struct S{
    ...
    Foo *ptrToFoo;
};

class Foo{ 
    Foo();
    ~Foo();
    ...
    S sname;
};
于 2012-10-26T13:49:40.093 に答える
0

S内でローカルに宣言できますFoo

class Foo
{
    struct S
    {
        Foo *ptrToFoo;
    };

    S sname;
};
于 2012-10-26T13:50:43.447 に答える