菱形继承和虚函数
来源:互联网 发布:md5加盐加密java代码 编辑:程序博客网 时间:2024/06/05 19:47
此篇博客主要介绍菱形虚拟继承和虚函数的混合情况下的模型分析。
一.首先介绍一下虚函数的实质内容
1.没有虚继承的虚函数
class A{public:int a;virtual void fun1(){cout << "A::fun1 " << endl;}};class B :public A{public:int b;virtual void fun1()//函数重写 {cout << "B::fun1 " << endl;}virtual void fun2(){cout << "B::fun2" << endl;}};int main(){B b;//创建一个B的对象 A a; b.b = 20;a.a = 10;b.a = 30;system("pause");return 0;}首先我们来看对象a的虚函数机制
接下里我们对B对象虚表里面的 函数进行验证,对象自己验证
typedef void(*fun)();//这里定义fun为函数指针类型fun *p = (fun *)*(int*)(&b);(*p)();//打印B::fun1 p++;//指向B::fun2 (*p)();//打印B::fun2
2.有虚继承的虚函数
首先看这个类的大小:
class A{public:int a;virtual void fun1(){cout << "A::fun1 "<< endl;}};class B :virtual public A{public:int b;virtual void fun1()//函数重写{cout << "B::fun1 " << endl;}virtual void fun2(){cout << "B::fun2" << endl;}};int main(){ B b; A a; b.b=20; a.a=10; sizeof(B); system("pause"); return 0;}
刚才无虚继承的类大小是12怎么加了个vurtual虚继承以后就变成了20呢?一下多了八个字节,接下来我们详细分析。
接下来打印验证:
typedef void(*fun)();//这里定义fun为函数指针类型fun *p = (fun *)*(int*)(&b);(*p)();p += 4;;(*p)();
3.菱形继承➕虚函数
首先给出基本代码:
class A{public:int _a;virtual void fun1(){cout << "A::fun1" << endl;}virtual void fun2(){cout << "A::fun2" << endl;}};class B1 : virtual public A{public:int _b1;virtual void fun1(){cout << "B1::fun1" << endl;}virtual void fun3(){cout << "B1::fun3" << endl;}};class B2 :virtual public A{public:int _b2;virtual void fun1(){cout << "B2::fun1" << endl;}virtual void fun4(){cout << "B2::fun4" << endl;}};class C :public B1,public B2{public:int _c;virtual void fun1(){cout << "C::fun1" << endl;}virtual void fun3(){cout << "C::fun3" << endl;}virtual void fun4(){cout << "C::fun4" << endl;}virtual void fun5(){cout << "C::fun5" << endl;}};int main(){cout <<"A:"<< sizeof(A) << endl;cout << "B1:"<<sizeof(B1) << endl;cout << "B2:"<<sizeof(B2) << endl;cout << "C:"<<sizeof(C) << endl;A a;B1 b1;B2 b2;C c;a._a = 10;b1._a = 10;b1._b1 = 20;b2._b2 = 30;b2._a = 10;c._c = 40;c._a = 10;c._b1 = 20;c._b2 = 30;system("pause");return 0;}
先来看看每个对象的大小然后我在逐个对象分析其模型
注意这里的B是B1,图上写的是B
接下来打印验证
typedef void(*fun)();//这里定义fun为函数指针类型fun *p = (fun *)*(int*)(&c);(*p)();//C::fun3(*(p + 1))();//C::fun5(*(p + 3))();//C::fun4(*(p + 5))();//C::fun1(*(p + 6))();//A::fun2
总结:1.无虚继承时在虚函数中,派生类中的虚函数非基类重写,则将其放置在继承来的虚函数表后面,不重新开辟虚函数表,并且将派生类中重写的虚函数替换基类中的虚函数
2.有虚继承虚函数时,派生类中的虚函数如果不是基类的重写的话,新开辟一个虚函数表将未重写虚函数放进去,将继承来的虚函数表放在其后面,并且将重写的替换
3.菱形继承+虚函数时,最重要的一点就是在,最低层的派生类中(上述例子就是C),只有一份基类(A)的虚表,并且在其模型(C模型)的最下面。并且将其没有重写的虚函数放在第一个继承模型(B1)的虚函数表下面,而且将其重写的也要替换为自己的。
阅读全文
0 0
- 菱形继承和虚函数
- 菱形继承和菱形虚继承
- 带有虚函数的菱形继承和带有虚函数的菱形虚继承
- 菱形继承和虚继承
- 菱形继承和虚继承
- 菱形继承和菱形虚继承的对象模型
- 菱形继承的虚函数表
- 带虚函数的菱形虚拟继承
- 菱形继承 虚继承
- 菱形继承和菱形虚拟继承探索
- C++菱形继承和菱形虚拟继承
- C++继承和菱形继承中的虚继承
- (C++)继承、菱形继承和虚继承的那些事儿
- 菱形继承(虚函数)->菱形虚拟继承(虚函数)->多态系列问题
- C++: 虚表和菱形虚拟继承
- 虚表和菱形虚拟继承
- C++中的继承关系、访问限定符,六个默认成员函数以及菱形继承和虚继承
- 子类默认函数的写法&菱形继承&虚继承
- 通过分析块设备驱动的框架,知道如何来写驱动
- JQuery中的事件和动画
- python 初学者环境安装问题
- python 多线程
- 商旅网站用户画像的解决方案
- 菱形继承和虚函数
- 新瓶装旧酒:全程无命令 GitHub Pages 创建您的博客站点
- opencv和opencv-contrib android版编译
- [NLP论文阅读] Learning Paraphrastic Sentence Embeddings from Back-Translated Bitext
- sdut-3332 数据结构实验之栈与队列五:下一较大值(一)
- spring上传文件报错Expected MultipartHttpServletRequest: is a MultipartResolver configured?
- 数人云PaaS Innovation 2017,重新定义PaaS进化
- Java的split详解
- 由 System.arraycopy 引发的巩固:对象引用 与 对象 的区别