在父类中添加虚函数,父类中调用这个虚函数,子类继承父类后,子类实现的虚函数就会在父类调用的时候自动响应;
一:例子:
如:计算机上链接多个摄像头,设计一个类,每一个对象可以关联一个摄像头,当图像获取的时候将图像通过虚函数传递给子类;
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 都是同样的方法;