C++类内存分布+钻石模型的解决方法
来源:互联网 发布:怎样申请淘宝号 编辑:程序博客网 时间:2024/04/29 13:58
C++类内存分布
#include<iostream>using namespace std;class Base{ private: int val; public: Base(int i = 0):val(i){cout<<val<<endl;} ~Base(){}};class Derived1 : public Base{ private: int a; public: Derived1(int i = 1):a(i){cout<<a<<endl;} };class Derived2 : public Base{ private: int b; public: Derived2(int i = 2):b(i){cout<<b<<endl;}};class Test : public Derived1, public Derived2{ private: int c; public: Test(int i = 3):c(i){cout<<i<<endl;}};int main(){ cout<<sizeof(Base)<<endl; cout<<sizeof(Derived1)<<endl; cout<<sizeof(Derived2)<<endl; cout<<sizeof(Test)<<endl; return 0;}
以下为上述各类在内存中的分布情况:
我们在基类中加上虚函数 我们再来看看类的内存分布:
由以上我们可以看出,类中多了一个指针成员
其实这个指针成员就是传说中的虚表指针
虚表是一个函数指针数组,它在编译程序时生成
虚表指针是一个函数指针数组的指针,在构造函数中,虚表指针被初始化指向虚表
在非虚继承的派生类中,派生类和基类公用一个虚表指针,这也是实现多态的基础,当我们用一个基类指针指向一个派生类对象,在调用函数时,我们会查阅虚表,进行相应的函数调用,从而实现多态.你可能会问那如果基类指针指向一个基类的对象,那么函数调用岂不是调用到了派生类的函数? 其实不是这样的,当基类指针指向一个基类对象时,它会直接调用基类的函数,而不会去查阅虚表. 需要指出的是查阅虚表需要进行解引用操作,故效率没有直接调用函数高,但是我们为了实现多态,付出这么一点代价也是值得的…
到现在为止,你发现以上的类有什么问题吗?
没错,基类Base的成员在Test类中存在两份,这就可能导致二义性的产生,那么如何解决这个问题呢?
答案是使用虚继承机制!
代码如下:
#include<iostream>using namespace std;class Base{ private: int val; public: Base(int i = 0):val(i){cout<<val<<endl;} virtual ~Base(){}};class Derived1 : virtual public Base{ private: int a; public: Derived1(int i = 1):a(i){cout<<a<<endl;} };class Derived2 : virtual public Base{ private: int b; public: Derived2(int i = 2):b(i){cout<<b<<endl;}};class Test : public Derived1, public Derived2{ private: int c; public: Test(int i = 3):c(i){cout<<i<<endl;}};int main(){ cout<<sizeof(Base)<<endl; cout<<sizeof(Derived1)<<endl; cout<<sizeof(Derived2)<<endl; cout<<sizeof(Test)<<endl; return 0;}
以下是上述类内存分布:
我们从以上类的内存分布可以看出,在使用了虚继承机制后,基类成员在派生类中只有一份拷贝,解决了二义性的问题.但是同时,虚继承使得我们和基类不能共用同一个虚表指针,故增加了维护多个虚表的开销!
总结: 当基类中含有虚函数时
1.每个类都将含有虚表指针,虚表在编译期间生成,虚表指针在构造函数中进行初始化
2.当为非虚继承时,派生类和基类共享一个虚表指针
3.当为虚继承时,可以解决钻石模型带来的二义性的问题,但是同时派生类不能和基类共享虚表指针,每个派生类都有两个指针,一个指向基类的虚表,一个指向自己的虚表,这也增加了维护虚表的难度!
- C++类内存分布+钻石模型的解决方法
- 钻石型继承模型的内存分布
- 钻石继承中的类的内存分布
- C 的内存分布
- 钻石型虚拟多重继承的C++对象内存模型
- 钻石型虚拟多重继承的C++对象内存模型
- C/C++的内存分布
- c程序的内存分布
- C程序的内存分布
- 类的内存分布
- 钻石的4C是什么?
- C/C++程序的内存分布
- c语言共用体的内存分布
- C语言程序的内存分布
- C++ 内存的分布
- C/C++进程内存的分布
- c++类的内存分布
- 波特“钻石”模型理论的基本内容
- 权限修饰符
- hdu 5191
- linux下grep命令详解
- C# Kinect Invoke()
- CI项目架构(2)---共用model、library、helper
- C++类内存分布+钻石模型的解决方法
- WPF深入浅出话资源
- Microsoft word 中的题注修改后更新的问题
- eclipse 配置ndk,sdk和svn
- httpclient2
- iOS 字体集(图文并茂)
- beyond compare diff report script
- Mac BetterZip破解
- 【LeetCode从零单排】No129 Sum Root to Leaf Numbers