请教深入浅出mfc中的一个示例程序,有点看不明白?

myjsy 2009-10-06 11:30:29
请教深入浅出mfc中的一个示例程序,有点看不明白?
为了提问题,我首先将代码发上来,一共是4个文件,我依次发上来:

1.mfc.h

#define BOOL int
#define TRUE 1
#define FALSE 0
#include <iostream.h>
class CObject
{
public:
CObject::CObject()
{
cout << "CObject Constructor \n" << endl;
}
CObject::~CObject(){cout << "CObject Destructor \n" << endl;}
};

class CCmdTarget:public CObject
{
public:
CCmdTarget::CCmdTarget()
{
cout << "CCmdTarget Construct \n" << endl;
}
CCmdTarget::~CCmdTarget(){cout << "CCmdTarget Destructor \n" << endl;}
};

class CWinThread:public CCmdTarget
{
public:
CWinThread::CWinThread()
{
cout << "CWinThread Constructor \n" << endl;
}
CWinThread::~CWinThread(){cout << "CWinThread Destructor \n" << endl;}

virtual BOOL InitInstance()
{
cout << "CWinThread::InitInstance" << endl;
return TRUE;
}

virtual int Run()
{
cout << "CWinThread::Run" << endl;
return 1;
}
};

class CWnd;

class CWinApp:public CWinThread
{
public:
CWinApp* m_pCurrentWinApp;
CWnd* m_pMainWnd;
public:
CWinApp::CWinApp()
{
m_pCurrentWinApp=this;
cout << "CWinApp Constructor this指针已传入\n " << endl;
}
CWinApp::~CWinApp()
{
cout << "CWinApp Destructor \n" << endl;
}

virtual BOOL InitApplication()
{
cout << "CWinApp::InitApplication" << endl;
return TRUE;
}

virtual BOOL InitInstance()
{
cout << "CWinApp::InitInstance" << endl;
return TRUE;
}

virtual int Run()
{
cout << "CWinApp::Run" << endl;
return CWinThread::Run();
}
};

class CDocument:public CCmdTarget
{
public:
CDocument::CDocument()
{
cout << "CDocument Constructor \n";
}
CDocument::~CDocument(){cout << "CDocument Destructor \n";}
};

class CWnd : public CCmdTarget
{
public:
CWnd::CWnd()
{
cout << "CWnd Constructor \n";
}
CWnd::~CWnd(){cout << "CWnd Destructor \n";}

virtual BOOL Create();
BOOL CreateEx();
virtual BOOL PreCreateWindow();
};


class CFrameWnd:public CWnd
{
public:
CFrameWnd::CFrameWnd()
{
cout << "CFrameWnd Constructor \n";
}
CFrameWnd::~CFrameWnd(){cout << "CFrameWnd Destructor \n";}
BOOL Create();
virtual BOOL PreCreateWindow();
};



class CView:public CWnd
{
public:
CView::CView()
{
cout << "CView Constructor \n";
}
CView::~CView(){cout << "CView Destructor \n";}
};

CWinApp* AfxGetApp();



2.mfc.cpp

#include "my.h"

extern CMyWinApp theApp;

BOOL CWnd::Create()
{
cout << "CWnd::Create" << endl;
return TRUE;
}

BOOL CWnd::CreateEx()
{
cout << "CWnd::CreateEx" << endl;
PreCreateWindow();
return TRUE;
}

BOOL CWnd::PreCreateWindow()
{
cout << "CWnd::PreCreateWindow" << endl;
return TRUE;
}

BOOL CFrameWnd::Create()
{
cout << "CFrameWnd::Create" << endl;
CreateEx();
return TRUE;
}

BOOL CFrameWnd::PreCreateWindow()
{
cout << "CFrameWnd::PreCreateWindow" << endl;
return TRUE;
}

CWinApp* AfxGetApp()
{
return theApp.m_pCurrentWinApp;
}



3.my.h

#include <iostream.h>
#include "mfc.h"

class CMyWinApp:public CWinApp
{
public:
CMyWinApp::CMyWinApp()
{
cout << "CMyWinApp Constructor \n" << endl;
}
CMyWinApp::~CMyWinApp()
{
cout << "CMyWinApp Destructor \n" << endl;
}
virtual BOOL InitInstance();

};

class CMyFrameWnd:public CFrameWnd
{
public:
CMyFrameWnd();
~CMyFrameWnd(){cout << "CMyFrameWnd Destructor \n";}
};





4.my.cpp

#include "my.h"

CMyWinApp theApp;

BOOL CMyWinApp::InitInstance()
{
cout << "CMyWinApp::InisInstance" << endl;
m_pMainWnd=new CMyFrameWnd;
return TRUE;
}

CMyFrameWnd::CMyFrameWnd()
{
cout << "CMyFrameWnd::CMyFrameWnd" << endl;
Create();
}

void main()
{
CWinApp* pApp=AfxGetApp();
pApp->InitApplication();
pApp->InitInstance();
pApp->Run();
}




好了,先发代码吗?下面再提问,否则有点乱。
...全文
121 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
MoXiaoRab 2009-10-06
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 myjsy 的回复:]
引用 12 楼 oyster2008 的回复:
调用CFrameWnd的函数,CFrameWnd派生自CWnd并且改写了PreCreateWinodw这个函数,而CMyFrameWnd派生自CFrameWnd并且自己没有改写PreCreateWindow函数,所以它调用的是它的父类的函数

是不是可以这样理解?
如果本类没有改写这个虚函数,则调用父类的函数,如果有多个父类的同名函数时,
则调用最靠近本类的函数,即离自已最近的虚函数,我这样理解对吗?

[/Quote]
这样理解不是不可以

其实是上下转型的概念。就像你Animal 是父类,Dog是子类,两者都有一样的方法名称

调用的时候,还是以Dog为准
oyster2008 2009-10-06
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 myjsy 的回复:]
引用 12 楼 oyster2008 的回复:
调用CFrameWnd的函数,CFrameWnd派生自CWnd并且改写了PreCreateWinodw这个函数,而CMyFrameWnd派生自CFrameWnd并且自己没有改写PreCreateWindow函数,所以它调用的是它的父类的函数

是不是可以这样理解?
如果本类没有改写这个虚函数,则调用父类的函数,如果有多个父类的同名函数时,
则调用最靠近本类的函数,即离自已最近的虚函数,我这样理解对吗?

[/Quote]
你这样理解也可以,在继承关系链上,CWnd算是CMyFrameWnd的祖父类了,而CFraemWnd才是CMyFraemWnd的真正父类,一个类如果没有改写虚函数,那么它调用的是继承关系链上与自己最近的一个类的同名虚函数
myjsy 2009-10-06
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 oyster2008 的回复:]
调用CFrameWnd的函数,CFrameWnd派生自CWnd并且改写了PreCreateWinodw这个函数,而CMyFrameWnd派生自CFrameWnd并且自己没有改写PreCreateWindow函数,所以它调用的是它的父类的函数
[/Quote]
是不是可以这样理解?
如果本类没有改写这个虚函数,则调用父类的函数,如果有多个父类的同名函数时,
则调用最靠近本类的函数,即离自已最近的虚函数,我这样理解对吗?
oyster2008 2009-10-06
  • 打赏
  • 举报
回复
调用CFrameWnd的函数,CFrameWnd派生自CWnd并且改写了PreCreateWinodw这个函数,而CMyFrameWnd派生自CFrameWnd并且自己没有改写PreCreateWindow函数,所以它调用的是它的父类的函数
myjsy 2009-10-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 tr0j4n 的回复:]
CWnd只是个基类,连个实例都没有。调用自然是调CFrameWnd::PreCreateWindow了,还用问吗?虚函数被重写了
[/Quote]
可是,CFrameWndb也是基类,也没有实例呀?
真正实例化的是
cmyframewnd呀,cframewnd和cwnd都是它的父类呀。
delphiwcdj 2009-10-06
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 myjsy 的回复:]
我说错了,PreCreateWindows()是虚函数,
另外,4楼朋友,你说错了,是调用第二个,我也是不明白为什么?
书上说是第二个,我测试也是第二个,我不明白的就是为什么会调用第二个,而不是调用第一个?

[/Quote]
虚函数的原理
推荐你看看http://blog.csdn.net/hairetz/archive/2009/04/29/4137000.aspx

MoXiaoRab 2009-10-06
  • 打赏
  • 举报
回复
汗...我看错了...本来该说CFrameWnd的,居然说成了前面那个....

MoXiaoRab 2009-10-06
  • 打赏
  • 举报
回复
CWnd只是个基类,连个实例都没有。调用自然是调CFrameWnd::PreCreateWindow了,还用问吗?虚函数被重写了
myjsy 2009-10-06
  • 打赏
  • 举报
回复
我说错了,PreCreateWindows()是虚函数,
另外,4楼朋友,你说错了,是调用第二个,我也是不明白为什么?
书上说是第二个,我测试也是第二个,我不明白的就是为什么会调用第二个,而不是调用第一个?
delphiwcdj 2009-10-06
  • 打赏
  • 举报
回复
怎么不是虚函数
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
你F12看下
delphiwcdj 2009-10-06
  • 打赏
  • 举报
回复
先CFrameWnd::PreCreateWindow()
myjsy 2009-10-06
  • 打赏
  • 举报
回复
这两个函数一个是父类,一个是子类,并且不是虚函数。
此时,调用哪一个呢?
当然,我知道调用的是cfrmewnd中的precreatewindow(),但是我不明白为什么?
MoXiaoRab 2009-10-06
  • 打赏
  • 举报
回复
自然是第一个了
myjsy 2009-10-06
  • 打赏
  • 举报
回复
我的问题,从main()中的
pApp->InitInstance();语句开始问,我想调用的过程:

1.
pApp->InitInstance();
2.
BOOL CMyWinApp::InitInstance()
{
cout << "CMyWinApp::InisInstance" << endl;
m_pMainWnd=new CMyFrameWnd;
return TRUE;
}

执行到,m_pMainWnd=new CMyFrameWnd;
3.
CMyFrameWnd::CMyFrameWnd()
{
cout << "CMyFrameWnd::CMyFrameWnd" << endl;
Create();
}
执行到 Create();这一句。

4.
BOOL CFrameWnd::Create()
{
cout << "CFrameWnd::Create" << endl;
CreateEx();
return TRUE;
}
执行到 CreateEx();这一句。

5.
BOOL CWnd::CreateEx()
{
cout << "CWnd::CreateEx" << endl;
PreCreateWindow();
return TRUE;
}

执行到 PreCreateWindow();这一句。
以上过程我全明白,就是到了这句,我不知下面应该如何走了。
因为有两个 PreCreateWindow()

就是下面两个:

BOOL CWnd::PreCreateWindow()
{
cout << "CWnd::PreCreateWindow" << endl;
return TRUE;
}

BOOL CFrameWnd::PreCreateWindow()
{
cout << "CFrameWnd::PreCreateWindow" << endl;
return TRUE;
}



此时应该调用哪一个呢?





arong1234 2009-10-06
  • 打赏
  • 举报
回复
把你想问的那段贴就好了,贴这么多干吗
zdcju 2009-10-06
  • 打赏
  • 举报
回复
以上这种形式,我也是第一次遇见,书上都没说过,不知道是不是和书上说的多态性本质一样
zdcju 2009-10-06
  • 打赏
  • 举报
回复
应该是调用的对象不同,导致PreCreateWindow() 如果是CWnd对象调用CreateEx()则调用CWnd::PreCreateWindow() ,如果是CFrameWnd对象调用CreateEx()则调用CFrameWnd::PreCreateWindow() 我写了个类似的结构,可以看看
#include "iostream.h"
class a
{
public:
void fun()
{
cout<<"aaaaaaa"<<endl;
}
void rr()
{
fun();
}
};
class b:public a
{
public:
void fun()
{
cout<<"bbbbbbbbbb"<<endl;
}
};

void main()
{
a sa,*psa;
b sb,*psb;
//sb.rr();
sa.rr();
}
sa,sb都调用父类的rr()但执行的fun()却不同,初学不知道这样解释对不
myjsy 2009-10-06
  • 打赏
  • 举报
回复

BOOL CWnd::CreateEx()
{
cout << "CWnd::CreateEx" << endl;
PreCreateWindow();
return TRUE;
}

BOOL CWnd::PreCreateWindow()
{
cout << "CWnd::PreCreateWindow" << endl;
return TRUE;
}

BOOL CFrameWnd::PreCreateWindow()
{
cout << "CFrameWnd::PreCreateWindow" << endl;
return TRUE;
}


其实我最不明白的就是,当调用
CWnd下的 CWnd::CreateEx()时,执行到:
PreCreateWindow();
时,为何不是调用相同级别的
cwnd下的:CWnd::PreCreateWindow()
而是去调用下一个级别的:
CFrameWnd::PreCreateWindow()
我知道这是多态,但是就是无法理解,
对于父类指针调用我能明白,但是这种形式我还是理解不了。


banhan1991 2009-10-06
  • 打赏
  • 举报
回复
虚函数就是说父类的指针在遇到多态性的时候尽量调用子类的同名函数(当然子类得定义了这个函数)。
如果子类没有定义该函数时(即与父类相比该函数的操作不变),多态性自动认为是父类的函数。

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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