C++重要性质04:虚拟函数与动态绑定
来源:互联网 发布:三线性优化开不开 编辑:程序博客网 时间:2024/05/17 22:26
序:大学四年浑浑噩噩,光阴虚度;值此毕业之际,如梦方醒;然亦无所悔恨,既有所悟,惟勤勉耳。近来研习《深入浅出MFC》,受益良多,故而摘抄一二,置此博文之中,以备不时翻阅。小子不才,无所增益,学而践之而已。此文摘自《深入浅出MFC》第二章C++的重要性质。
【虚拟函数与动态绑定】
虚拟函数是C++语言的多态性质以及动态绑定的关键,那么虚拟函数是怎么实现的?如果能够了解C++编译器对于虚拟函数的实现方式,我们就能够知道为什么虚拟函数可以做到动态绑定。
为了达到动态绑定(后期绑定)的目的,C++ 编译器通过某个表格,在执行时期「间接」调用实际上欲绑定的函数。这样的表格称为「虚拟函数表」(常被称为vtable)。每一个「内含虚拟函数的类别」,编译器都会为它做出一个虚拟函数表,表中的每一笔元素都指向一个虚拟函数的地址。此外,编译器当然也会为类别加上一项成员变量,一个指向该虚拟函数表的指针(常被称为vptr)。
class Class1
{
public :
m_data1;
m_data2;
memfunc();
virtual vfunc1();
virtual vfunc2();
virtual vfunc3();
};
Class1 对象实体在内存中占据这样的空间:
每一个由此类别衍生出来的对象,都有这么一个vptr。我们通过这个对象调用虚拟函数,事实上是通过vptr找到虚拟函数表,再找出虚拟函数的真正地址。奥妙在于这个虚拟函数表以及这种间接调用方式。
虚拟函数表的内容是依据类别中的虚拟函数声明次序一一填入函数指针的。衍生类别会继承基础类别的虚拟函数表(以及所有其它可以继承的成员),当我们在衍生类别中改写虚拟函数时,虚拟函数表就受了影响:表中元素所指的函数地址将不再是基础类别的函数地址,而是衍生类别的函数地址。
class Class2 : public Class1
{
public :
m_data3;
memfunc();
virtual vfunc2();
};
于是,一个「指向Class1所生对象」的指针,所调用的vfunc2 就是Class1::vfunc2(),而一个「指向Class2 所生对象」的指针,所调用的vfunc2 就是Class2::vfunc2。动态绑定机制,在执行时期,根据虚拟函数表,做出了正确的选择。
- C++重要性质04:虚拟函数与动态绑定
- C++重要性质05:虚拟函数与对象切割
- 学习笔记之深入浅出MFC 第8章 C++重要性质----虚拟函数与多态(Polymorphism)
- C++重要性质07:构造函数与析构函数
- B-样条基函数:重要性质
- 虚函数重要性质总结
- [C++]静态绑定与动态绑定
- 虚函数与动态绑定
- 虚函数与动态绑定
- 对虚拟函数动态绑定的一点认识
- 反正切函数的一个重要性质
- 虚函数,静态与动态绑定
- 虚函数表与动态绑定
- 学习笔记之深入浅出MFC 第8章 C++重要性质---构造函数与析构函数
- C++的重要性质:虚函数和多态性
- 高斯函数具有五个重要的性质
- KMP中的getnext函数中的周期原理,和重要性质
- 图像处理中高斯函数的重要性质
- 对于jQuery的click事件出现重复情况的对策
- 关于取模和取余的区别。
- NYOJ-23 取石子(一)
- Error MSB6006: “mt.exe”已退出,代码为 31
- 黑马程序员 —— C语言之关键字
- C++重要性质04:虚拟函数与动态绑定
- hdu1358 KMP循环节
- mysqli的认识与应用
- spark入门教程(3)--Spark 核心API开发
- Windows下Python包的pip安装
- 机器学习简史
- [leetcode]319. Bulb Switcher
- leetcode——17——Letter Combinations of a Phone Number
- 解决Cordova开发iOS的app界面被状态栏覆盖的问题