• 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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    这是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;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    这里加了代码进行比较。并设了断点,在调试时。确实,AfxGetApp()==this,这个语句等于直接调用
    if (!OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL))
    … …

    不过用不用if都没关系。调试证实了猜想是对的,最后都调用了theApp的处理函数OnFileNew()。

    无论何时,当需要对一个写好的类成员函数调试时,都可以派生一个新的类,只包含一个成员函数,跟要调试的成员函数重名。复制它的代码并修改,因而重载它。如果它不是虚函数,添加virtual关键字把它临时改为虚函数,从而在调试时的程序中替换它。所以,不用为了调试,在写好的代码上乱改了!

  • 相关阅读:
    64ELK日志分析系统
    C# + Oracel 批量插入数据(List,Array等)
    数据结构作业4-图
    让“作用域和闭包”说人话
    CF1477D Nezzar and Hidden Permutations 题解
    搜索技术【广度优先搜索】 - 嵌套广度优先搜索 【POJ No. 1475】 推箱子 Pushing Boxes
    C++11多线程thread使用详解
    【开源】基于Vue和SpringBoot的智能教学资源库系统
    Java SE 中的变量、数据类型和字符串类型以及类型转换和类型提升
    Opengl实例7:glm(0.9.8.5)库 +矩阵旋转+课后作业
  • 原文地址:https://blog.csdn.net/aaasssdddd96/article/details/132725713