C++的继承(十):虚函数和Debug

有时候,对写好的代码有疑问,所以需要调试。实际例子比如这个:

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关键字把它临时改为虚函数,从而在调试时的程序中替换它。所以,不用为了调试,在写好的代码上乱改了!

你可能感兴趣的:(c++,开发语言,继承,虚函数)