问个多态的基本问题

try_okey 2007-03-10 11:31:26
void Manager::Run()
{
while( WaitForSingleObject(m_hKillEvent, 0) != WAIT_OBJECT_0 ){
PTRMSG pMsg = m_msgQueue.WaitForNormalMessage(1000);
if( pMsg ){
OnMessage(pMsg);
DeleteMessage(pMsg);
}
}
}
------
这里函数里OnMessage是个虚函数,在Manager.h中的定义是:
virtual BOOL OnMessage(PTRMSG pMsg) = NULL;
但实际的实现是Manager类的子类实现的,但有好几个子类实现,从上面的直接调用OnMessage(pMsg)虚函数,那么到底是指向哪个子类怎么看的?(隐藏指针?
从WaitForNormalMessage函数返回的给PTRMSG pMsg 指针的赋值体现的?)


附:
PTRMSG CMessageQueue::WaitForNormalMessage(int dwMilliseconds)
{
DWORD dw = WaitForSingleObject(m_hEvent, dwMilliseconds);
if( dw == WAIT_OBJECT_0 )
return PopupMessage();
return NULL;
}

PTRMSG CMessageQueue::PopupMessage()
{
PTRMSG pRet = NULL;
EnterCriticalSection(&m_lock);
POSITION pos = m_listMsg.GetHeadPosition();
if( pos ){
pRet = (PTRMSG)m_listMsg.GetAt(pos);
m_listMsg.RemoveAt(pos);
if( m_listMsg.GetCount() )
SetEvent(m_hEvent);
// else ResetEvent(m_hEvent); // 自动事件不需要设置
}
LeaveCriticalSection(&m_lock);
ASSERT(pRet);
return pRet;
}

...全文
186 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jixingzhong 2007-03-10
  • 打赏
  • 举报
回复
虽然 pMsg 是一个基类类型,
但是在实际调用的时候,
传递的应该是某个派生子类类型的对象,
这个对象中存在 OnMessage 方法的实现,
调用这个实现就是了 ~

如果需要了解更多细节,
建议看看 inside C++ object model
jixingzhong 2007-03-10
  • 打赏
  • 举报
回复
virtual BOOL OnMessage(PTRMSG pMsg) = NULL;
但实际的实现是Manager类的子类实现的,但有好几个子类实现,从上面的直接调用OnMessage(pMsg)虚函数,那么到底是指向哪个子类怎么看的?(隐藏指针?
从WaitForNormalMessage函数返回的给PTRMSG pMsg 指针的赋值体现的?)
==================================
到底指向哪个子类,
就是看的 在实际调用时候,
传入的参数是什么类型的了。

传入的参数是一个子类类型的对象,
这个传入的子类对象中有这个 OnMessage 方法的实现,
那么就调用的当前对象的 OnMessage 方法。

也就是,
它不需要判断类型,
就是调用传递进来的对象的 OnMessage 方法就是了 ~
try_okey 2007-03-10
  • 打赏
  • 举报
回复
...
try_okey 2007-03-10
  • 打赏
  • 举报
回复
整个调用过程如下:
m_pSmsManager->Create();

其中,m_pSmsManager是SmsManager类的对象,但在该类中没有实现Create函数,因此是调用父类Manager里的Create函数(虚函数),如下:
BOOL CManager::Create(UINT nMaxStoreMsgCount)
{
m_msgQueue.SetMaxStoreMsgCount(nMaxStoreMsgCount);

m_hKillEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if( !m_hKillEvent )
return FALSE;

unsigned int dwThreadID;
m_hThread = (HANDLE)_beginthreadex(
NULL, 0, ThreadProc, (LPVOID)this, 0, &dwThreadID);
if( !m_hThread ){
CloseHandle(m_hKillEvent);
m_hKillEvent = NULL;
return FALSE;
}
return TRUE;
}
这里启动一个线程,启动ThreadProc函数,如下:
unsigned int WINAPI CManager::ThreadProc(LPVOID lpParam)
{
CManager* pVM = (CManager*)lpParam;
ASSERT(pVM);
pVM->Run();//虚函数
return 0L;
}
Run函数的实现如下:
void CManager::Run()
{
while( WaitForSingleObject(m_hKillEvent, 0) != WAIT_OBJECT_0 ){
PTRMSG pMsg = m_msgQueue.WaitForNormalMessage(1000);
if( pMsg ){
OnMessage(pMsg);//虚函数
DeleteMessage(pMsg);
}
}
}
问题一:
这个就是我问题里问的函数,里面调用OnMessage函数,那么调OnMessage的对象是不是就是最初调用m_pSmsManager->Create()里的m_pSmsManager?也就是说,这里调用的OnMessage函数应是类SmsManager里实现的OnMessage函数?

问题二:
另外,CManager::ThreadProc函数里的Run函数也是类CManager定义的虚函数,但子类SmsManager没有实现该函数,因此调用了CManager类里的;假如SmsManager类里对Run重新实现了,是不是这里就应该调用的是SmsManager类里的?

问题三:
pVM->Run()这个调用里的pVM由CManager* pVM = (CManager*)lpParam定义,这里lpParam的具体含义是什么?CManager* pVM = (CManager*)lpParam赋值后,pVM指向CManager的对象?

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧