MFC 虚函数
2016-06-27 00:05
597 查看
// Test.cpp : Defines the class behaviors for the application. // #include "stdafx.h" #include "Test.h" #include "TestDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CTestApp BEGIN_MESSAGE_MAP(CTestApp, CWinApp) //{{AFX_MSG_MAP(CTestApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTestApp construction CTestApp::CTestApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } ///////////////////////////////////////////////////////////////////////////// // The one and only CTestApp object CTestApp theApp; /* 1.全局函数(程序入口): _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // call shared/exported WinMain return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); // 全局函数 } 看见了吗?里面调用了AfxWinMain(),也就说MFC把对WinMain()的调用转化为对AfxWinMain()的调用,这更加说明,即使在MFC中, 也没有什么其它神奇的方法能够跳过或换掉对WinMain()的调用。 2.在WINMAIN.CPP文件中,实现了AfxWinMain()。 AfxWinMain()才实际调用CWinApp->InitApplication()、CWinApp->->InitInstance()完成系统初始化。 int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { ASSERT(hPrevInstance == NULL); int nReturnCode = -1; CWinThread* pThread = AfxGetThread(); // 得到进程指针 CWinApp* pApp = AfxGetApp(); // CWinApp 是 CWinThread 的爸 // AFX internal initialization if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow)) goto InitFailure; // App global initializations (rare) if (pApp != NULL && !pApp->InitApplication()) // 虚函数 子类实现了用子类的 子类没实现 用父类的 goto InitFailure; // Perform specific initializations if (!pThread->InitInstance()) // // 虚函数 子类实现了用子类的 子类没实现 用父类的 { if (pThread->m_pMainWnd != NULL) { TRACE0("Warning: Destroying non-NULL m_pMainWnd\n"); pThread->m_pMainWnd->DestroyWindow(); } nReturnCode = pThread->ExitInstance(); goto InitFailure; } nReturnCode = pThread->Run(); InitFailure: #ifdef _DEBUG // Check for missing AfxLockTempMap calls if (AfxGetModuleThreadState()->m_nTempMapLock != 0) { TRACE1("Warning: Temp map lock count non-zero (%ld).\n", AfxGetModuleThreadState()->m_nTempMapLock); } AfxLockTempMaps(); AfxUnlockTempMaps(-1); #endif AfxWinTerm(); return nReturnCode; } */ //DEL BOOL CTestApp::InitInstance() //DEL { //DEL // Standard initialization //DEL // If you are not using these features and wish to reduce the size //DEL // of your final executable, you should remove from the following //DEL // the specific initialization routines you do not need. //DEL //DEL CTestDlg dlg; //DEL m_pMainWnd = &dlg; //DEL int nResponse = dlg.DoModal(); //DEL if (nResponse == IDOK) //DEL { //DEL // TODO: Place code here to handle when the dialog is //DEL // dismissed with OK //DEL } //DEL else if (nResponse == IDCANCEL) //DEL { //DEL // TODO: Place code here to handle when the dialog is //DEL // dismissed with Cancel //DEL } //DEL //DEL // Since the dialog has been closed, return FALSE so that we exit the //DEL // application, rather than start the application's message pump. //DEL return FALSE; //DEL } BOOL CTestApp::InitApplication() { // TODO: Add your specialized code here and/or call the base class return CWinApp::InitApplication(); } BOOL CTestApp::InitInstance() { // TODO: Add your specialized code here and/or call the base class return CWinApp::InitInstance(); }
虚函数用法就是
1.使用子类定义对象
CTestApp theApp;
2.使用父类指针指向子类对象
CWinThread* pThread = AfxGetThread(); // 得到进程指针 0x0052d6c0
CWinApp* pApp = AfxGetApp(); // CWinApp 是 CWinThread 的爸 0x0052d6c03.用父类对象调用虚函数(实现到哪个子类,就会调用哪个子类哪个虚函数)
#include <iostream>
using namespace std;
class Parent
{
protected:
int i;
int j;
public:
virtual void Show()
{
printf("Parent()\n");
}
void fun(Parent & p)
{
Show();
}
};
class Child1 : public Parent
{
public:
virtual void Show()
{
printf("Child1\n");
}
};
class Child2 : public Child1 // 在父类中的构造函数中条用了虚函数 所以当子类实现了 因为多肽就会使用子类的 当子类不实现 就使用父类的
{
public:
// virtual void Show()
// {
// printf("Child2\n");
// }
};
int main()
{
Child1 c1;
Child2 c2;
// Parent *p[] = {&c1, &c2};
//
// p[0]->fun(c1);
// p[1]->fun(c2);
// p[0]->Show();
// p[1]->Show();
Parent &p = c2;
p.fun(c2);
return 0;
}如果Child2中不实现那个虚函数,在调用的时候回调用父类的函数,所以就像MFC一样,给了用户一个借口,如果用户不实现,程序会默认去使用父类实现的虚函数,如果子类中实现了虚函数,那就使用子类默认的函数.
就像MFC CTestApp::InitInstance()中如果在 CTestApp中没有被实现,就会使用
BOOL CWinApp::InitInstance()
{
return TRUE;
}
相关文章推荐
- c#中虚函数的相关使用方法
- C#与.net高级编程 C#的多态介绍
- C#中面向对象编程机制之多态学习笔记
- C#中的多态深入理解
- C#中多态、重载、重写区别分析
- 设计引导--一个鸭子游戏引发的设计理念(多态,继承,抽象,接口,策略者模式)
- C++虚函数及虚函数表简析
- C++之普通成员函数、虚函数以及纯虚函数的区别与用法要点
- 构造函数不能声明为虚函数的原因及分析
- C++虚函数表实例分析
- C++虚函数的实现机制分析
- C++中虚函数与纯虚函数的用法
- C# 面向对象三大特性:封装、继承、多态
- C/C++杂记 虚函数的实现的基本原理(图文)
- javascript每日必学之多态
- c#基础学习之多态
- 深入探讨C++父类子类中虚函数的应用
- PHP面向对象三大特点学习(充分理解抽象、封装、继承、多态)
- Lua多重继承代码实例
- 从汇编看c++中多态的应用