C++之类内存布局实例演示④---补充(14)《Effective C++》
来源:互联网 发布:重新激活免费网络通信 编辑:程序博客网 时间:2024/06/13 22:22
1)针对多重继承中的虚函数而言,如果子类中没有重写多个父类中共有的virtual方法,看看关于子类的vfptr到底是父类中哪个的???
#include <iostream>using namespace std;class Base1{private: int i;public: Base1(int i) :i(i=10){ } virtual void show(){ cout << "Base1:" << this->i << endl; } virtual ~Base1(){ cout << "Base1析构开始。。。" << endl; }};class Base2{private: int j;public: Base2(int j) :j(j = 20){ } virtual void show(){ cout << "Base2:" << this->j << endl; } virtual ~Base2(){ cout << "Base2析构开始。。。" << endl; }};class Derived :public Base1, public Base2{private: int k;public: Derived(int i, int j, int k) :Base1(i), Base2(j), k(k){ } /*virtual void show(){ cout << "Derived:" << k << endl; }*/ virtual ~Derived(){ cout << "Derived析构开始。。。" << endl; }};int main(){ Base1* b1 = new Derived(1, 2, 3); b1->show(); Base2* b2 = new Derived(4, 5, 6); b2->show(); delete b1; delete b2; return 0;}
运行结果:
结果表明,当子类没有对多个父类共有的virtual方法进行重写时候,子类中的vfptr可能会有多个,那么子类调用的时候到底调用哪个呢?运行结果告诉我们适合哪个就调用哪个啦,哈哈哈!
2)多个父类的共有的virtual函数在子类中被进行了重写,那么子类中的vfptr也会有多个,同样的需要调用哪个呢?
#include <iostream>using namespace std;class Base1{private: int i;public: Base1(int i) :i(i=10){ } virtual void show(){ cout << "Base1:" << this->i << endl; } virtual ~Base1(){ cout << "Base1析构开始。。。" << endl; }};class Base2{private: int j;public: Base2(int j) :j(j = 20){ } virtual void show(){ cout << "Base2:" << this->j << endl; } virtual ~Base2(){ cout << "Base2析构开始。。。" << endl; }};class Derived :public Base1, public Base2{private: int k;public: Derived(int i, int j, int k) :Base1(i), Base2(j), k(k){ } virtual void show(){ cout << "Derived:" << k << endl; } virtual ~Derived(){ cout << "Derived析构开始。。。" << endl; }};int main(){ Base1* b1 = new Derived(1, 2, 3); b1->show(); Base2* b2 = new Derived(4, 5, 6); b2->show(); delete b1; delete b2; return 0;}
运行结果:
看到结果你就明白啦,这是一种优化体系,所以,Derived重写部分的东西会出现在Derived中的第一个vfptr指向的虚函数表后面,因此,调用的肯定为第一个vfptr指向的虚函数表啦(内存结构②中有相应的图示,可以仔细研究一下)~~~
注意这种结构中,Derived class中的内存布局,里面有两个vfptr指针,vfptr中指向的show()函数都是&Derived::show(),所以无论我们怎样调用都会调用的是Derived::show(),所以被重载啦!!!
3)针对虚继承,我们可以进行如下探索:
#include <iostream>using namespace std;class Base{public: virtual void show() = 0;};class Base1:virtual public Base{private: int i;public: Base1(int i) :i(i=10){ } virtual void show(){ cout << "Base1:" << this->i << endl; } virtual ~Base1(){ cout << "Base1析构开始。。。" << endl; }};class Base2:virtual public Base{private: int j;public: Base2(int j) :j(j = 20){ } virtual void show(){ cout << "Base2:" << this->j << endl; } virtual ~Base2(){ cout << "Base2析构开始。。。" << endl; }};class Derived :public Base1, public Base2{private: int k;public: Derived(int i, int j, int k) :Base1(i), Base2(j), k(k){ } virtual void show(){ cout << "哈哈哈哈,发生了什么,我为什么一定要出现啊???" << endl; } virtual ~Derived(){ cout << "Derived析构开始。。。" << endl; }};int main(){ Base1* b1 = new Derived(1, 2, 3); b1->show(); Base2* b2 = new Derived(4, 5, 6); b2->show(); delete b1; delete b2; return 0;}
运行结果:
结果可以发现,虚继承确保基类在其菱形子类中的数据只会出现一份,所以,上例中Derived::show()必须重写,因为不重写的话C++不知道究竟需要调用哪种。。。
具体可以参考:C++内存分布(带有虚继承)—补充(11)《Effective C++》
阅读全文
0 0
- C++之类内存布局实例演示④---补充(14)《Effective C++》
- C++中的类内存布局②---补充(12)《Effective C++》
- C++之成员函数内存布局③---补充(13)《Effective C++》
- C++类内存分布(带有虚继承)①---补充(11)《Effective C++》
- C++中的virtual关键字---补充(1)《Effective C++》
- C++类型转换操作符---补充(8)《Effective C++》
- C语言内存知识补充
- Objective-C语言学习之类和实例
- 一起talk C栗子吧(第一百二十九回:C语言实例--C程序内存布局一)
- 一起talk C栗子吧(第一百三十回:C语言实例--C程序内存布局二)
- 一起talk C栗子吧(第一百三十一回:C语言实例--C程序内存布局三)
- C中内存堆栈的布局---linux 简单实例
- c程序内存布局
- C/C++ 内存布局
- Objective-C内存布局
- C/C++ 内存布局
- Objective-C内存布局
- Objective-C内存布局
- java反射的简单应用
- hololens初识
- shell四剑客之grep
- 事件绑定的第二种形式
- POJ 1061 青蛙的约会 一元线性同余方程
- C++之类内存布局实例演示④---补充(14)《Effective C++》
- OpenCV笔记:ROI
- JavaScript BOM
- Ubuntu14.04安装python后conda命令未找到
- 使用javascript解析xxx.xml文档将数据加载到xxx.html文档中的表格元素中
- 关于注意力
- 【算法系列】——重新认识动态规划
- 让我们一起聊聊“窗口函数”
- 我们为什么需要威胁情报?