派生クラスのメンバ関数のポインタ
MFC の CWinThread
をカプセル化するクラスを作ろうと思ったのが始まりだったのですが、AfxBeginThread
に、派生クラスのメンバ関数は、たとえstatic
であっても渡せないようです。ポインタのサイズが違うらしいんですね。(参考: ロベールのC++教室 - 第58章 メンバ関数ポインタ天国 -)
カプセル化したいのはワーカスレッドだったのですが、結局、こんな感じで落ち着きました。以下、基本クラスのヘッダファイルと実装ファイルです。
// MyThread.h: ワーカースレッドのラッパクラス // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_MYTHREAD_H__F7F40085_1ED7_4C5F_AA67_A72835BFBE04__INCLUDED_) #define AFX_MYTHREAD_H__F7F40085_1ED7_4C5F_AA67_A72835BFBE04__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include <vector> #include <afxmt.h> class CMyThread { public: CMyThread(); virtual ~CMyThread(); static UINT WaitForAllThread(); static void SetMaxThread( UINT uMaxThread ); UINT Begin(); friend UINT MapThreadProc( LPVOID lpParam ); protected: virtual UINT ThreadProc( LPVOID lpParam ) = 0; // ワーカスレッドのメイン処理 static std::vector<CMyThread*> sm_vecInstances; static UINT sm_uCounter; static CCriticalSection sm_CriticalSection; static UINT sm_uMaxThread; HANDLE m_hThread; CWinThread* m_lpThread; BOOL m_fEndThread; }; #endif // !defined(AFX_MYTHREAD_H__F7F40085_1ED7_4C5F_AA67_A72835BFBE04__INCLUDED_)
// MyThread.cpp: CMyThread クラスのインプリメンテーション // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MyThread.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif std::vector<CMyThread*> CMyThread::sm_vecInstances; UINT CMyThread::sm_uCounter = 0; CCriticalSection CMyThread::sm_CriticalSection; UINT CMyThread::sm_uMaxThread = 10; ////////////////////////////////////////////////////////////////////// // 構築/消滅 ////////////////////////////////////////////////////////////////////// CMyThread::CMyThread() : m_hThread( (HANDLE)NULL ) , m_lpThread( NULL ) { ; } CMyThread::~CMyThread() { } UINT CMyThread::Begin() { m_lpThread = AfxBeginThread( ( AFX_THREADPROC )( MapThreadProc ), this ); m_hThread = m_lpThread->m_hThread; sm_vecInstances.push_back( this ); return 0; } void CMyThread::SetMaxThread( UINT uMaxThread ) { sm_uMaxThread = uMaxThread; return; } UINT CMyThread::WaitForAllThread() { UINT num = sm_vecInstances.size(); HANDLE hThreads[MAXIMUM_WAIT_OBJECTS]; int iRet = 0; { for ( int i = 0; i < num; i++ ) hThreads[ i ] = ( ( CMyThread* )sm_vecInstances[ i ] )->m_hThread; } switch ( WaitForMultipleObjects( num, hThreads, TRUE, INFINITE ) ) { case WAIT_TIMEOUT: case WAIT_FAILED: iRet = 1; default: ; } return 0; } UINT MapThreadProc(LPVOID lpParam) { CMyThread* lpThis = (CMyThread *)lpParam; return lpThis->ThreadProc( lpParam ); }
派生クラス側は、CMyThread を継承して、ThreadProc 関数をオーバーライドします。
トラックバック
- このエントリーにトラックバック:
- http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/295
コメント
えぇそうなんですか?
静的メンバなら普通の関数ポインタと同じ扱いだと思って
いたんですが、
ところで、
クラスの静的メンバが派生クラスだとサイズが違うだなんて
提示されたロベールに書いてありましたっけ?
(今はリンク切れになってますけど。)
自分の記憶では静的メンバについては触れていなかったような・・・
具体的に試しても問題なさそうでよくわからないし
すごく気になるので
もしよろしければ駄目な例を教えていただけませんか?
ってもう古い記事だし見ていないか・・・