让静态成员函数具有多态性(浅谈如何使回调函数具有多态性)

// Windows编程中,经常要用到回调函数.要封装具有回调函数的对象

//就将回调函数设为类的静态成员函数,而在C++,静态成员函数是没有多态性的.

//如何使静态函数具有"多态性的行为",下面通过封装thread来说明这一技巧

 

//主要体现在static unsigned  int __stdcall ThreadProxy( void *pvParam )

//int Create()两个函数上面

 

 

//MyThread.h

#pragma once

typedef unsigned(__stdcall *pThreadFunc)(void*);

#define smBeginThread(psa,cbStack,pfnStartAddr,pvParam, /

    dwCreate,pdwThreadId)                                       /

    (HANDLE)_beginthreadex(psa,(unsigned int)cbStack,                         /

    (pThreadFunc)pfnStartAddr,(void*)pvParam,dwCreate,(unsigned*)pdwThreadId)

class CMyThread

{

private:

    //禁止拷贝和将对象赋值给其他对象

    CMyThread(CMyThread&);

    CMyThread & operator =(CMyThread&);

private:

    static unsigned  int __stdcall ThreadProxy( void *pvParam );

protected:

    virtual int Run(void *pvParam)=0;

    ~CMyThread(void);        //使对象只能从堆中创建

protected:

    HANDLE _hThread;

public:

    enum _DESTROY_TYPE{_dtWAIT=0,   //阻塞等待线程直到线程退出

       _dtTRY,                            //如果线程已经退出,则删除,否则立刻返回

       _dtTERMINATE};                  //强制关闭线程

   

public:

    CMyThread(void);

   

    int Create(LPVOID pvParam,DWORD dwCreate=CREATE_SUSPENDED

       ,LPSECURITY_ATTRIBUTES psa=NULL,SIZE_T cbStack=0

       ,LPDWORD pdwThreadId=NULL);

    int Suspend();

    int Resume();

    int Terminate( DWORD dwExitCode); 

    //_hThread==NULL,立刻返回-1; 不开预料的错误:返回-2

    //当成功删除,返回0,否则返回STILL_ACTIVE

    int Destroy(_DESTROY_TYPE dt,DWORD & dwExitCode,DWORD const dwWaitTimes);

    BOOL GetExitCode(DWORD &dwExitCode);

    HANDLE GetHandle();

    DWORD GetId();

   

};

 

 

 

 

 

 

//MyThread.cpp

 

#include "StdAfx.h"

#include <Windows.h>

#include <process.h>

#include "./mythread.h"

#ifndef ASSERT

#include <cassert>

#define ASSERT(s) assert(s)

#endif

namespace

{

    class _ThreadProxy

    {

       friend CMyThread;

       _ThreadProxy(_ThreadProxy&);

       _ThreadProxy& operator =(_ThreadProxy);

    private:

       CMyThread* _pThis;

       void *_pvParam;

       _ThreadProxy(CMyThread*thread,void *pvParam)

           :_pThis(thread)

           ,_pvParam(pvParam)

       {

       }

    };

}

CMyThread::CMyThread(void)

:_hThread(0)

{

}

 

CMyThread::~CMyThread(void)

{

    if (_hThread)

    {

       CloseHandle(_hThread);

    }

    _hThread=NULL;

}

unsigned int CMyThread::ThreadProxy( void *pvParam )

{

    _ThreadProxy *proxy=(_ThreadProxy*)pvParam;

    ASSERT(proxy);

    CMyThread*pThis=proxy->_pThis;

    void *param=proxy->_pvParam;

    delete proxy;

    return (unsigned int)pThis->Run(param);

}

 

int CMyThread::Create(LPVOID pvParam,DWORD dwCreate/* =CREATE_SUSPENDED  */,

                          LPSECURITY_ATTRIBUTES psa/* =NULL */

                          ,SIZE_T cbStack/* =0  */,LPDWORD pdwThreadId/* =NULL */)

{

    _hThread=smBeginThread(psa,cbStack,ThreadProxy,

       (new _ThreadProxy(this,pvParam))   ,dwCreate,pdwThreadId);

    ASSERT(_hThread);

    return _hThread?0:-1;

}

int CMyThread::Suspend()

{

    ASSERT(_hThread);

    return ::SuspendThread(_hThread);

}

int CMyThread::Resume()

{

    ASSERT(_hThread);

    return ::ResumeThread(_hThread);

}

int CMyThread::Terminate( DWORD dwExitCode)

{

    ASSERT(_hThread);

    return ::TerminateThread(_hThread,dwExitCode);

}

HANDLE CMyThread::GetHandle()

{

    return _hThread;

}

DWORD CMyThread::GetId()

{

    ASSERT(_hThread);

    return ::GetThreadId(_hThread);

}

BOOL CMyThread::GetExitCode(DWORD & dwExitCode)

{

    ASSERT(_hThread);

    return ::GetExitCodeThread(_hThread,&dwExitCode);

}

 

//_hThread==NULL,立刻返回-1; 不开预料的错误:返回-2

//当成功删除,返回0,否则返回返回1

int CMyThread::Destroy(_DESTROY_TYPE dt,DWORD & dwExitCode,

                           DWORD const dwWaitTimes/* =0 */)

{

    int iRet;

    if (!_hThread)

    {

       delete this;

       return -1;

    }

    switch(dt) {

    case _dtTRY:

       if (GetExitCodeThread(_hThread,&dwExitCode)==0){return -2;}

        if (dwExitCode==STILL_ACTIVE)   {   return 1;}

       break;

 

    case _dtWAIT:

       ASSERT(dwWaitTimes>=0);

       iRet=WaitForSingleObject(_hThread,dwWaitTimes); 

       if (iRet==WAIT_TIMEOUT)

       {

           dwExitCode=STILL_ACTIVE;

           return 1;

       }

       if (iRet=WAIT_OBJECT_0)

       {

           GetExitCodeThread(_hThread,&dwExitCode);        

       }     

       break;

    case _dtTERMINATE:

       if (::GetExitCodeThread(_hThread,&dwExitCode)==0){return -2;}

       if (dwExitCode==STILL_ACTIVE)

       {

           ::TerminateThread(_hThread,dwExitCode);         

       }

       break;

    }

    delete this;

    return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值