有时候,对写好的代码有疑问,所以需要调试。实际例子比如这个:
BOOL CWinApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo)
{
BOOL bResult = TRUE;
switch (rCmdInfo.m_nShellCommand)
{
case CCommandLineInfo::FileNew:
if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL))
OnFileNew();
if (m_pMainWnd == NULL)
bResult = FALSE;
break;
...
}
...
class CEx03App:public CWinApp {...};
CEx03App theApp;
这是MFC的一个片断。这里的if语句比较令人困惑。因为应用程序的theApp继承了CWinApp。应用程序只有一个theApp。那么这里的AfxGetApp()找的不就是this指针吗,为什么还要AfxGetApp()去找?而且,无论这里的OnCmdMsg()是为真而在里面调用了ID_FILE_NEW对应的处理函数OnFileNew(),还是为假因而调用了if块中的OnFileNew(),总是要调用OnFileNew(),不是吗?
为了调试这个代码,重新派生一个CApp类,代码只包含一个函数,名字也叫ProcessShellCommand。这是个虚函数,因此被重载了。
class CApp:public CEx03App
{
public:
BOOL ProcessShellCommand(CCommandLineInfo& rCmdInfo);
};
BOOL CApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo)
{
BOOL bResult = TRUE;
switch (rCmdInfo.m_nShellCommand)
{
void *ppp;
case CCommandLineInfo::FileNew:
ppp =AfxGetApp();
if (ppp!= this) {
bResult = FALSE;
}
if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL))
{
if (ppp!= this) {
bResult = FALSE;
}
OnFileNew();
}
if (m_pMainWnd == NULL)
bResult = FALSE;
break;
...
}
CApp theApp;
这里加了代码进行比较。并设了断点,在调试时。确实,AfxGetApp()==this,这个语句等于直接调用
if (!OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL))
… …
不过用不用if都没关系。调试证实了猜想是对的,最后都调用了theApp的处理函数OnFileNew()。
无论何时,当需要对一个写好的类成员函数调试时,都可以派生一个新的类,只包含一个成员函数,跟要调试的成员函数重名。复制它的代码并修改,因而重载它。如果它不是虚函数,添加virtual关键字把它临时改为虚函数,从而在调试时的程序中替换它。所以,不用为了调试,在写好的代码上乱改了!