包装模式

来源:互联网 发布:js经典面试题 编辑:程序博客网 时间:2024/04/28 13:57

相信用C++的朋友都喜欢封装自己的类,我也是一样。为什么要封装呢?因为封装能给我们未来的工作带来好处:
1、通过封装可以把现有接口改变成自己比较习惯的接口来使用;
2、通过封装可以把相关的功能集中到一起,便于使用;
3、通过封装可以把我们所需要使用的功能子集从原有的众多功能中分离出来,便于记忆与使用;
4、封装可以使得我们写兼容不同平台的代码变得更加简洁;
5、通过封装可以避免以后重复写繁琐的相同的代码,提高工作效率;

我们平常所做的这种封装其实就是一种包装模式。

工作中经常需要使用线程,但C++标准又没有线程的封装,于是就自己简单封装一下,便于以后使用。

//------------------------------thread.h开始--------------------------------------
#include <vector>
using namespace std;

class CThread
{
public:
typedef unsigned (__stdcall 
*THREAD_PROC)(void *arg );
typedef 
void * THANDLE;
enum CREATE_FLAG{
   RUNNING 
= 0//立即运行线程
   SUSPENDED = 4 //创建线程但不立即运行
}
;
enum {INVALID_THANDLE = -1L };

public:
CThread();
virtual ~CThread();

static inline bool isvalid( THANDLE h )
{
   
return h != (THANDLE)INVALID_THANDLE;
}


public:

//职责:创建一个以proc为起始地址的线程。失败返回INVALID_THANDLE,成功返回线程句柄。
static THANDLE create_thread(
   THREAD_PROC proc,   
//[in]线程起始地址
   void *arg,     //[in]线程参数
   unsigned initflag = 0//[in]CREATE_FLAG的其中一个
   unsigned *thrdid = 0//[out]线程ID
   void *security = 0,   //[in]安全描述
   unsigned stack_size = 0 //[in]线程栈空间大小
   );

//职责:等待线程ht结束并关闭句柄。timeout[-1=无线等待,0=不等待,n=等待n秒]。成功返回0,否则返回-1。
static int wait_for_exit(THANDLE ht,int timeout=-1);

//职责:运行挂起的线程ht。成功返回0,否则返回-1。
static int resume_thread(THANDLE ht);

public:

//职责:创建一个以虚函数thread_proc为起始地址的线程。失败返回-1,成功返回0。
int create(
   unsigned thread_num 
= 1,
   unsigned initflag 
= 0//[in]CREATE_FLAG的其中一个
   unsigned *thrdid = 0,
   
void *security = 0,
   unsigned stack_size 
= 0);

//职责:等待线程thread_proc结束并关闭句柄。timeout[-1=无限等待,0=不等待,n=等待n秒]。成功返回0,否则返回-1。
int wait(int timeout=-1);

//职责:运行挂起的线程thread_proc。成功返回0,否则返回-1。
int resume();

protected:
virtual unsigned thread_proc();
private:
static unsigned __stdcall thread_start_addr(void *param);
private:
vector
<THANDLE> m_thandles;

}
;
//------------------------------thread.h结束--------------------------------------

//------------------------------thread.cpp开始--------------------------------------
#include "thread.h"
#include 
<windows.h>
#include 
<process.h>

CThread::CThread(
void) : m_thandles(0)
{
}


CThread::
~CThread(void)
{
}


//职责:创建一个以proc为起始地址的线程。失败返回INVALID_THANDLE,成功返回线程句柄。
/*static*/
CThread::THANDLE CThread::create_thread(
THREAD_PROC proc,   
//[in]线程起始地址
void *arg,     //[in]线程参数
unsigned initflag /*= 0*///[in]CREATE_FLAG的其中一个
unsigned *thrdid /*= 0*///[out]线程ID
void *security /*= 0*/,   //[in]安全描述
unsigned stack_size /*= 0*/ //[in]线程栈空间大小
)
{
uintptr_t h 
= _beginthreadex(
   security,
   stack_size,
   proc,
   arg,
   initflag,
   thrdid );

return (h) ? (CThread::THANDLE)h : (CThread::THANDLE)(CThread::INVALID_THANDLE);
}


unsigned CThread::thread_proc()
{
return 0;
}


//职责:等待线程ht结束并关闭句柄。timeout[-1=无线等待,0=不等待,n=等待n秒]。成功返回0,否则返回-1。
/*static*/
int CThread::wait_for_exit(THANDLE ht,int timeout/*=-1*/)
{
DWORD wt 
= ::WaitForSingleObject( ht, timeout );
if( wt == WAIT_OBJECT_0 )
{
   ::CloseHandle( ht );
   
return 0;
}

return -1;
}


//职责:运行挂起的线程ht。成功返回0,否则返回-1。
/*static*/
int CThread::resume_thread(THANDLE ht)
{
DWORD rv 
= ::ResumeThread( ht );
return ( (DWORD)-1 == rv ) ? -1 : 0;
}

/*static */
unsigned __stdcall CThread::thread_start_addr(
void *param)
{
CThread 
*pself = (CThread *)param;
return pself->thread_proc();
}



//职责:创建一个以虚函数thread_proc为起始地址的线程。返回创建成功的线程个数。
int CThread::create(
      unsigned thread_num
/* = 1*/,
      unsigned initflag 
/*= 0*///[in]CREATE_FLAG的其中一个
      unsigned *thrdid /*= 0*/,
      
void *security /*= 0*/,
      unsigned stack_size 
/*= 0*/)
{
if!this->m_thandles.empty() )
{
   
return -1;
}


for( size_t i = 0; i<thread_num; i++ )
{
   CThread::THANDLE h 
= CThread::create_thread( CThread::thread_start_addr, this, initflag, thrdid, security, stack_size );
   
if( (CThread::THANDLE)CThread::INVALID_THANDLE == h )
   
{
    
break;
   }

   
else
   
{
    
this->m_thandles.push_back( h );
   }

}

return (int)m_thandles.size();
}


//职责:等待线程thread_proc结束并关闭句柄。timeout[-1=无线等待,0=不等待,n=等待n秒]。成功返回0,否则返回-1。
int CThread::wait(int timeout /*=-1*/)
{
size_t num 
= this->m_thandles.size();
if( num < 1 )
{
   
return 0;
}

DWORD wt 
= ::WaitForMultipleObjects( (DWORD)num, &this->m_thandles[0], TRUE, timeout );
if( ( WAIT_TIMEOUT == wt ) || ( WAIT_FAILED == wt ) )
{
   
return -1;
}


for( size_t i=0; i<num; i++)
{
   ::CloseHandle( 
this->m_thandles[i] );
}

m_thandles.clear();
return 0;
}


//职责:运行挂起的线程thread_proc。成功返回0,否则返回-1。
int CThread::resume()
{
size_t num 
= this->m_thandles.size();
for( size_t i=0; i<num; i++)
{
   resume_thread( 
this->m_thandles[i] );
}

return 0;
}

//------------------------------thread.cpp结束--------------------------------------

 使用方法:从CThread派生一个类,重写thread_proc函数。

#include "thread.h"
#include 
<iostream>
using namespace std;

class CMyThread : public CThread
{
public:
CMyThread() 
{
}

virtual ~CMyThread()
{
}

protected:
unsigned thread_proc()
{//线程工作函数
   
//写线程工作的代码
   return 0;
}

}
;

int _tmain(int argc, _TCHAR* argv[])
{
CMyThread a;

//创建两个线程
a.create( 2 );

//等待线程执行完
a.wait( -1 );

return 0;
}
原创粉丝点击