在父类中添加虚函数,父类中调用这个虚函数,子类继承父类后,子类实现的虚函数就会在父类调用的时候自动响应;


一:例子:

如:计算机上链接多个摄像头,设计一个类,每一个对象可以关联一个摄像头,当图像获取的时候将图像通过虚函数传递给子类;

class A
 {
 public:


virtual void BufferCB( BYTE * pBuf, int nLen ) = 0; //设计为纯虚函数,这样必须继承实现;
//virtual void BufferCB( BYTE * pBuf, int nLen ){};




 public:
static UINT thread_t(PVOID pParam )
{
A * pA = (A*)pParam;

                int i = 0;

while(1)
{

char buf[100] = {0};
       sprintf( buf, "BufferCB pBuf is: %d", i++); 
 
pA->BufferCB( (BYTE*)buf, strlen(buf)+1 );


Sleep(1000);
}


return 0;
}


void start()
{
AfxBeginThread( thread_t, this );
}
  


 };



 class New_A : public A
 {
 public:
void BufferCB( BYTE * pBuf, int nLen )
{
//AfxMessageBox( CString( (char*)pBuf ) );


OutputDebugStr( CString(( char* )pBuf) );
}
 };
//应用:
//说明:从这个例子可以看出 每一New_A的对象都对应着一个自己的线程,每个线程处理自己相关的类中的内容(  int i = 0;);
void tA()
 {
 New_A  * New_A_obj_1 = new New_A;
 New_A  * New_A_obj_2 = new New_A;


   New_A_obj_1->start();
   New_A_obj_2->start();
 }


二:例子:

另一个模式: 

如:计算机上只有一个摄像头, 但是 有多个模块(类)中都需要这个摄像头的图像;

        或者如:计算机时间, 当时间变化时, 所有和时间显示获取相关的模块都要获取到时间的变化;


解决这个问题一般有两个模式,

1:拉模式: 就是启动一个线程,实时监控对象状态(摄像头,时间),如果有变化,就获取相关的数据;

2:推模式:相关对象,对摄像头,或时间模块进行“消息注册”,如果有变化,就通知(调用)相关对象的函数;


一般情况,拉模式比较浪费系统资源,而且效率较低,建议用推模式;

class B
 {
 public:


virtual void BufferCB( BYTE * pBuf, int nLen ) = 0;
//virtual void BufferCB( BYTE * pBuf, int nLen ){}; public:
B()
{
m_vector_B.push_back( this );


if ( m_vector_B.size() == 1 )
{
AfxBeginThread( thread_t_All, 0 );
}
}


static std::vector<B *> m_vector_B;
//
static UINT thread_t_All(PVOID pParam )
{




while(1)
{
if ( m_vector_B.size() > 0 )
{
static int i = 0;
char buf[100] = {0};
sprintf( buf, "BufferCB pBuf is: %d", i++); 


for ( int n = 0; n<m_vector_B.size(); n++)
{
B * pB = m_vector_B.at(n);


pB->BufferCB( (BYTE*)buf, strlen(buf)+1 );
}






} 


Sleep(1000);
}


return 0;
}


void start_all()
{
AfxBeginThread( thread_t_All, 0 );
}


 };


 vector<B*> B::m_vector_B;




 class New_B : public B
 {
 public:
void BufferCB( BYTE * pBuf, int nLen )
{
//AfxMessageBox( CString( (char*)pBuf ) );


OutputDebugStr( CString(( char* )pBuf) );
}
 };
//应用:
//说明:线程的启动,和指针的获取在__super类的构造函数中获取,关于指针和继承的内存模型就不多说了;
//这样每一创建的对象在数据变化的时候都可以获取同样的数据了;
//如时间变化了,__super类就循环的通知了所有注册的(在m_vector_B中的)对象模块了;
void tB()
 {
New_B * New_B_obj_1  = new  New_B;
New_B * New_B_obj_2  = new  New_B;;
 }
//

关于上述另个方法,都是父类通过虚函数调用子类实现的虚函数;

不同的是,方法一,会启动多个线程,每个对象维护一个自己相关的线程,获取的都是自己模块的数据;每个模块数据一般不同;如:例子中,每个对象获取不同摄像的图像;

方法二:只启动一个线程,所有的对象模块获取的都是相同的数据;如:所有对象获取的都是同一摄像的相同图像;


这类模式方法在 MFC的CWnd消息,Qt的QWidget的event 都是同样的方法;