c++多态的实现 VC++消息映射的实现
2007-10-11 13:09
316 查看
http://blog.csdn.net/gxnu/archive/2007/09/26/1801870.aspx
多态是如何利用这个虚函数表实现的呢?看下面的代码:
struct Super
{
int data;
virtual int add(int i){return i;};
virtual string toString()=0;
};
class Sub: public Super
{
public:
string toString()
{
return string("Sub class");
}
};
Super* s = new Sub();
cout<<s->toString()<<endl;
delete s;
输出”Sub class”。
VC++消息映射的思考
作者:郝庆欣
在学习VC++的时候,大家都不可避免的用到消息映射。我们都知道C++是一种面向对象的编程语言,VC++中为什么这样来实现消息映射呢?
首先要明白一个包含了消息处理的Windows程序是如何工作的。
一般来说一个包含了消息处理的Windows程序至少要包含两个函数
第一个:
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
);
第二个:
long FAR PASCAL WndProc(HWND hWnd,WORD message,WORD wParam,LONG lParam);
我们不必纠缠程序实现的细节,
!,eW国r[无]Sc-2A
只要明白在第一个函数WinMain中要注册WndProc函数,通俗一些的理解就是WinMain告诉Windows系统,听着,我知道你要产生很多消息,我这里有一个WndProc函数负责处理你传递来的各种消息。当然消息的格式都是系统规定好的。
其次要明白C++中是如何实现多态性的。
我们知道多态性实现的关键是晚绑定(或者称为后期绑定),其实质就是编译器并没有在编译期间指定调用函数的绝对地址,而是指定了某个类内部该函数的偏移地址。
为了实现上面的功能,编译器为我们作了手脚
1、 在每个带有虚函数的类中,D.#$5育管网4b!T2Rj管f编译器秘密放置了一个指针,称为Vpointer
2、 当系统运行时,
%X^:件+垠理|uxWS专
为每个类创建一个VTABLE,其中包含了可以调用虚函数地址。
3、 Vpointer出始化,指向VTABLE,通过在Vtable中偏移,来找到正确的需要调用的函数地址。
然后是MFC对Window API进行的封装
当我们利用MFC框架开发程序的时候,尤其是开发界面应用程序的时候,必定要用到CWnd或者派生于CWnd的类。根据面向对象的设计原则,对于CWnd的一些通用函数,例如窗口大学改变(OnSize),窗口移动(OnMove),最好是在CWnd中声明为虚函数,然后在继承的类里面重载他们。但是,这样以来,每个相关的派生类都要有一个Vpointer和一套记录Vtable,而CWnd中通用函数是如此至多,CWnd的派生类也很多,必然会导致系统在运行是占用过多的资源(内存),这样显然是不合适的。
那么MFC是如何实现的呢?
答案就是在CWnd基类中尽可能的少用虚函数,采用消息映射机制来代替。
大家可以看一下CWnd的类中的函数,就会发现这一点。
上面这个函数就不是虚函数。
最后的问题消息映射是如何实现的呢?
用一句话说,就是利用宏定义来实现面向过程的消息处理。
例如在VC中有如下的消息映射宏。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_COMMAND(ID_FONT_DROPDOWN, DoNothing)
END_MESSAGE_MAP()
经过编译后,代码被替换为如下形式(这只是作讲解,实际情况比这复杂得多):
//BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
CMainFrame::newWndProc(...)
{
switch(...)
{
//{{AFX_MSG_MAP(CMainFrame)
// ON_WM_CREATE()
case(WM_CREATE):
OnCreate(...);
break;
//}}AFX_MSG_MAP
// ON_COMMAND(ID_FONT_DROPDOWN, DoNothing)
case(WM_COMMAND):
if(HIWORD(wP)==ID_FONT_DROPDOWN)
{
DoNothing(...);
}
break;
//END_MESSAGE_MAP()
}
}
这样,
~Z[._R理业供v[供~y
kkPuq}72V}[Kne育教垠@
C络rCp;6=+K专^}T3rk
$%Q软\%育HKS理A;b+垠RL垠
$H无Lg'网T垠G的
VC++就消除了对部分虚拟函数的需要,从而节省了内存空间。
参考资料:
Thingking in C++,Bruce Eckel;
http://www.vchelp.net/ 闻怡洋
寒岩之上,唯我独行---小朱
多态是如何利用这个虚函数表实现的呢?看下面的代码:
struct Super
{
int data;
virtual int add(int i){return i;};
virtual string toString()=0;
};
class Sub: public Super
{
public:
string toString()
{
return string("Sub class");
}
};
Super* s = new Sub();
cout<<s->toString()<<endl;
delete s;
输出”Sub class”。
VC++消息映射的思考
作者:郝庆欣
在学习VC++的时候,大家都不可避免的用到消息映射。我们都知道C++是一种面向对象的编程语言,VC++中为什么这样来实现消息映射呢?
首先要明白一个包含了消息处理的Windows程序是如何工作的。
一般来说一个包含了消息处理的Windows程序至少要包含两个函数
第一个:
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
);
第二个:
long FAR PASCAL WndProc(HWND hWnd,WORD message,WORD wParam,LONG lParam);
我们不必纠缠程序实现的细节,
!,eW国r[无]Sc-2A
只要明白在第一个函数WinMain中要注册WndProc函数,通俗一些的理解就是WinMain告诉Windows系统,听着,我知道你要产生很多消息,我这里有一个WndProc函数负责处理你传递来的各种消息。当然消息的格式都是系统规定好的。
其次要明白C++中是如何实现多态性的。
我们知道多态性实现的关键是晚绑定(或者称为后期绑定),其实质就是编译器并没有在编译期间指定调用函数的绝对地址,而是指定了某个类内部该函数的偏移地址。
为了实现上面的功能,编译器为我们作了手脚
1、 在每个带有虚函数的类中,D.#$5育管网4b!T2Rj管f编译器秘密放置了一个指针,称为Vpointer
2、 当系统运行时,
%X^:件+垠理|uxWS专
为每个类创建一个VTABLE,其中包含了可以调用虚函数地址。
3、 Vpointer出始化,指向VTABLE,通过在Vtable中偏移,来找到正确的需要调用的函数地址。
然后是MFC对Window API进行的封装
当我们利用MFC框架开发程序的时候,尤其是开发界面应用程序的时候,必定要用到CWnd或者派生于CWnd的类。根据面向对象的设计原则,对于CWnd的一些通用函数,例如窗口大学改变(OnSize),窗口移动(OnMove),最好是在CWnd中声明为虚函数,然后在继承的类里面重载他们。但是,这样以来,每个相关的派生类都要有一个Vpointer和一套记录Vtable,而CWnd中通用函数是如此至多,CWnd的派生类也很多,必然会导致系统在运行是占用过多的资源(内存),这样显然是不合适的。
那么MFC是如何实现的呢?
答案就是在CWnd基类中尽可能的少用虚函数,采用消息映射机制来代替。
大家可以看一下CWnd的类中的函数,就会发现这一点。
CWnd::OnMove
afx_msg void OnMove( int x, int y );上面这个函数就不是虚函数。
最后的问题消息映射是如何实现的呢?
用一句话说,就是利用宏定义来实现面向过程的消息处理。
例如在VC中有如下的消息映射宏。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_COMMAND(ID_FONT_DROPDOWN, DoNothing)
END_MESSAGE_MAP()
经过编译后,代码被替换为如下形式(这只是作讲解,实际情况比这复杂得多):
//BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
CMainFrame::newWndProc(...)
{
switch(...)
{
//{{AFX_MSG_MAP(CMainFrame)
// ON_WM_CREATE()
case(WM_CREATE):
OnCreate(...);
break;
//}}AFX_MSG_MAP
// ON_COMMAND(ID_FONT_DROPDOWN, DoNothing)
case(WM_COMMAND):
if(HIWORD(wP)==ID_FONT_DROPDOWN)
{
DoNothing(...);
}
break;
//END_MESSAGE_MAP()
}
}
这样,
~Z[._R理业供v[供~y
kkPuq}72V}[Kne育教垠@
C络rCp;6=+K专^}T3rk
$%Q软\%育HKS理A;b+垠RL垠
$H无Lg'网T垠G的
VC++就消除了对部分虚拟函数的需要,从而节省了内存空间。
参考资料:
Thingking in C++,Bruce Eckel;
http://www.vchelp.net/ 闻怡洋
寒岩之上,唯我独行---小朱
相关文章推荐
- vc++实现反射式数据库模版(3.序列化、反序列化与消息映射)
- (网摘好文)C++多态技术的实现和反思
- vc中消息映射的 分析
- 一个消息队列类的实现C++
- C++多态的实现及原理详细解析
- matlab jet color mapping C / C++ / VC 实现
- C++对象布局及多态实现探索之内存布局(转载)
- 【C++转】C++多态的实现及原理详细解析
- C++对象布局及多态实现探索之内存布局
- 多态在 Java 和 C++ 编程语言中的实现比较
- 潘凯:C++对象布局及多态实现的探索(四)
- 潘凯:C++对象布局及多态实现的探索(八)
- VC++编译问题汇总1 单链表的表示和实现,基于c++
- 在VC++ 6.0下利用消息实现内部进程通讯
- 从MVC架构到C++的多态实现
- C++多态的实现原理
- 消息映射的服务器的设计与实现
- C++多态中的实现要用指针,而不是虚基类(接口)的对象
- C语言模拟实现C++的继承多态
- C++多态的实现原理