深入C++对象模型&虚函数表
来源:互联网 发布:java输入输出流考题 编辑:程序博客网 时间:2024/05/16 15:53
多态的实现机制:
C++中虚函数的主要作用就是用来实现多态,就是使用基类的指针或者引用调用重写的虚函数,当父类的指针或引用指向父类对象时调用的是父类虚函数,当指向子类对象时调用的是子类的虚函数。那么这又是怎么实现的呢???
这都是通过虚函数表实现的,虚函数表是通过一块连续内存来存储虚函数的地址。这张表解决了虚函数重写(地址进行覆盖)的问题 。在有虚函数的对象实例中都有一张虚函数表,虚函数表就像一张地图,指明了实际调用的虚函数函数。
例:
class Base{public: Base() :_b(1){} virtual void fun1() { } virtual void fun2() { }private: int _b;};
虚函数表的最后一个元素是一个空指针。
既然我们知道了虚函数的地址,那么就可以通过过找到这块地址来调用这个虚函数。这也导致了多态的不安全性,效率降低。
typedef void (* pfun)();void PrintfBase(pfun *_ppfun){ int i = 0; for (i = 0; _ppfun[i] != NULL; i++) { _ppfun[i] (); }}void test(){ Base b; PrintfBase((pfun *)*((int *)(&b)));}
1、单继承对象模型
class Base{public: Base() :_b(1){} virtual void fun1() { cout << "Base::fun1()" <<endl; } virtual void fun2() { cout << "Base::fun2()" << endl; }private: int _b;};class Deriver :public Base{public: Deriver() :_d(2){} virtual void fun1() { cout << "Deriver::fun1()" << endl; } virtual void fun3() { cout << "Deriver::fun3()" << endl; }private: int _d;};typedef void (* pfun)();void PrintfBase(pfun *_ppfun){ int i = 0; for (i = 0; _ppfun[i] != NULL; i++) { _ppfun[i] (); }}void test(){ Base b; PrintfBase((pfun *)*((int *)(&b)));}
2、多重继承的对象模型
class Base1{public: Base1() :_b1(1){} virtual void fun1() { cout << "Base1::fun1()" <<endl; } virtual void fun2() { cout << "Base1::fun2()" << endl; }private: int _b1;};class Base2{public: Base2() :_b2(2){} virtual void fun1() { cout << "Base2::fun1()" << endl; } virtual void fun2() { cout << "Base1::fun2()" << endl; }private: int _b2;};class Deriver :public Base1,public Base2{public: Deriver() :_d3(3){} virtual void fun1() { cout << "Deriver::fun1()" << endl; } virtual void fun3() { cout << "Deriver::fun3()" << endl; }private: int _d3;};
3、菱形继承的对象模型
class Base{public: Base() :_b1(1){} virtual void fun1() { cout << "Base1::fun1()" << endl; } virtual void fun2() { cout << "Base1::fun2()" << endl; }private: int _b1;};class Base2:public Base{public: Base2() :_b2(1){} virtual void fun1() { cout << "Base2::fun1()" << endl; } virtual void fun3() { cout << "Base2::fun2()" << endl; }private: int _b2;};class Base3:public Base{public: Base3() :_b3(1){} virtual void fun1() { cout << "Base3::fun1()" << endl; } virtual void fun3() { cout << "Base3::fun2()" << endl; }private: int _b3;};class Deriver:public Base2,public Base3{public: Deriver() :_d3(3){} virtual void fun1() { cout << "Deriver::fun1()" << endl; } virtual void fun4() { cout << "Deriver::fun3()" << endl; }private: int _d3;};
4、菱形的虚拟继承
<span style="font-size:14px;">class Base{public: Base() :_b1(1){} virtual void fun1() { cout << "Base1::fun1()" << endl; } virtual void fun2() { cout << "Base1::fun2()" << endl; }private: int _b1;};class Base2:virtual public Base{public: Base2() :_b2(2){} virtual void fun1() { cout << "Base2::fun1()" << endl; } virtual void fun3() { cout << "Base2::fun2()" << endl; }private: int _b2;};class Base3:virtual public Base{public: Base3() :_b4(3){} virtual void fun1() { cout << "Base3::fun1()" << endl; } virtual void fun3() { cout << "Base3::fun2()" << endl; }private: int _b3;};class Deriver:public Base2,public Base3{public: Deriver() :_d3(4){} virtual void fun1() { cout << "Deriver::fun1()" << endl; } virtual void fun4() { cout << "Deriver::fun4()" << endl; }private: int _d4;};</span>
3 0
- 深入C++对象模型&虚函数表
- 深入探索C++对象象模型--拷贝构造函数、对象模型
- 【深入探索c++对象模型】c++中构造函数调用虚函数的讨论
- 【C++】虚函数在不同继承方式中的对象模型
- 对《深入C++对象模型》中的一个疑问——虚函数表的type_info的位置
- C++对象模型之虚函数表
- 多态、虚函数表、对象模型
- 【深入探索c++对象模型】抽象类和纯虚函数的理解
- 深入理解C++对象模型默认构造函数笔记
- 深入探索C++对象模型--C++构造函数
- 《深入C++面向对象模型》之拷贝构造函数
- 深入探索C++对象模型之拷贝构造函数
- 深入探索C++对象模型之内联函数
- 深入探索C++对象模型之构造函数扩展
- 深入理解C++对象模型之构造函数
- 深入理解C++对象模型之拷贝构造函数
- 深入探索c++虚函数继承模型
- 深入理解C++对象模型-成员函数的本质以及虚函数的实现(非虚继承)
- SDUTACM 顺序表应用1:多余元素删除之移位算法
- Codeforces Problem 709B Checkpoints(分类讨论)
- 用js实现段落多余文字省略显示
- 使用ajaxFileUpload上传文件流至服务器,同时提交多个参数
- java HttpsURLConnection 实现https请求
- 深入C++对象模型&虚函数表
- Git基础命令的使用——详细教程2
- 除复合索引外,哪些情况下不适合用索引
- TextView和ListView的滑动
- java基础学习总结——GUI编程(一)
- MultiByteToWideChar function
- dump代码提取
- leetcode No111. Minimum Depth of Binary Tree
- Mask在iPad2,iPad mini上导出的坑