通过虚函数继承,父类调用子类中函数
2014-07-09 18:56
281 查看
在父类中添加虚函数,父类中调用这个虚函数,子类继承父类后,子类实现的虚函数就会在父类调用的时候自动响应;
一:例子:
如:计算机上链接多个摄像头,设计一个类,每一个对象可以关联一个摄像头,当图像获取的时候将图像通过虚函数传递给子类;
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 都是同样的方法;
一:例子:
如:计算机上链接多个摄像头,设计一个类,每一个对象可以关联一个摄像头,当图像获取的时候将图像通过虚函数传递给子类;
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 都是同样的方法;
相关文章推荐
- C#中通过类来继承两个接口,父类实例化接口中的方法,子类继承父类,调用方法
- java类继承中父类调用子类函数的问题
- C#中通过类来继承两个接口,父类实例化接口中的方法,子类继承父类,调用方法
- 父类的正常成员函数子类可以使用,并不是继承下来 的,子类是怎么调用父类的函数 : 可能是利用了一种叫函数名联编的方法.没有隐藏的情况下用函数名字来决定调用的函数.
- C++ 类的继承,子类以及之类的对象 对父类成员函数的访问权限
- pb中父类动态调用子类的函数和事件方法
- 在子类释放时,先释放子类资源,然后调用父类的释放函数释放父类资源
- 在子类中调用父类被隐藏的函数的方法
- 父类与子类之间静态函数的调用以及函数参数的传递
- PHP父类调用子类方法,CodeIgniter中DB的继承关系
- C++子类调用父类覆盖的函数
- 子类和父类之间继承中构造函数的调用(一)
- java中父类子类的继承与函数重写
- C++ 继承中子类与父类虚函数入栈顺序 及父类私有虚函数的调用方式
- 关于子类继承父类,父类调用被子类重载的方法是输出什么
- c++子类能从父类中继承父类的静态成员函数吗
- 父类调用子类和虚构函数应用小结
- 虚函数与继承子类构造与析构函数调用问题
- java中的继承(子类调用父类构造方法还不懂)
- 子类虚函数C++ 继承中子类与父类虚函数入栈顺序 及父类私有虚函数的调用方式