2011-12-31 6 views
3

EDIT:私は完全に間違っているようです。このスレッドを閉じてください。ガー。レコードの クラスフレンドそのものを作る

、以下のコンパイルと動作します:

class ForeverAlone 
{ 
private: 
    int m_friends; 
    HANDLE m_handle; 

public: 
    ForeverAlone() 
    { 
    m_handle = CreateThread(NULL, 0, &ForeverAlone::SadThread, reinterpret_cast<void*>(this), 0, NULL); 
    } 

    ~ForeverAlone() 
    { 
    if (m_handle != NULL) 
     CloseHandle(m_handle); 
    } 

protected: 
    static unsigned long WINAPI SadThread(void* param) 
    { 
    ForeverAlone* thisObject = reinterpret_cast<ForeverAlone*>(param); 

    // is there any way for me to access: 
    thisObject->m_friends; 
    } 
}; 

元の質問:私はにオブジェクトを渡す静的保護スレッドの方法を、持っています。どういうわけかクラスfriend自身を作成し​​てプライベートメンバーにアクセスできますか?

+2

本当に必要ですか? –

+0

ええ、私はメンバーの* looooot *を持っているので、私はそれらのすべてのアクセサを作成したくないです。 –

+0

@Jonathan Lingle:ほとんどの現代のIDEは、アクセサの生成に手間取っています。メンテナンス性の面でそれは良い選択肢ではないでしょうか? – Asaph

答えて

10

すべてのクラスメソッド、静的かどうかは、自動的にクラスの「友人」です。フレンドは、外部関数とクラスがクラスにアクセスできるようにするために使用されます。クラスは常に独自の "友人"です。

1

この操作を行います。その後、コールバックでちょうどあなたの機能にアクセス

extern "c" DWORD __stdcall CInterfaceSadThread(LPVOID lpThreadParameter); 

class ForeverAlone 
{ 
    private: 
    int m_friends; 
    HANDLE m_handle; 

    public: 
    ForeverAlone() 
    { 
     m_handle = CreateThread(NULL, 0, 
           &CInterfaceSadThread, 
           // 
      // You may get arguments about using static_cast here 
      // I still prefer reinterpret_cast as it makes it stick out 
      // Thus I check it more carefully when I see it. 
      // For this situation it works correctly 
      // As casting to void* and back to the original are guaranteed. 
           reinterpret_cast<void*>(this), 
           0, NULL); 
    } 

    ~ForeverAlone() 
    { 
     if (m_handle != NULL) 
     CloseHandle(m_handle) 
    } 

    protected: 
    friend DWORD CInterfaceSadThread(LPVOID lpThreadParameter); 
    DWORD WINAPI SadThread() 
    { 
     // Do Stuff here 
     // Note: Just because you get here does not mean that the object is finished 
     //  initializing. The parent thread may have been suspended after this 
     //  one was created. Thus checking the state of member variables at this 
     //  point is dangerous unless you can guarantee that construction has finished 

     return result; 
    } 
}; 

を。

extern "c" DWORD __stdcall CInterfaceSadThread(LPVOID lpThreadParameter) 
{ 
    // Note: You can only cast back to ForeverAlone* so be carefull 
    //  Hence I use reinterpret_cast as this forces me to double check. 
    ForeverAlone* alone = reinterpret_cast<ForeverAlone*>(lpThreadParameter); 
    return alone->SadThread(); 
} 
+0

C関数ラッパーは必要ありません。 'SadThread()'を 'static'として宣言し、' CreateThread() 'に直接渡します。それはうまく動作します。 –

+1

@ RemyLebeau-TeamB:間違っています。静的関数のABIがC ABIと同じであることは事故である。この習慣に入るのはまったく悪い習慣です。 –

+1

完全に正しいが、OPが尋ねてきたものではない。彼はちょうど厄介なサンプルプログラムを持っています。 –

関連する問題