虚继承和虚函数对c++对象存储模型的影响(类/对象的大小)
2017-03-02 21:43
330 查看
首先重新回顾一下关于类/对象大小的计算原则:
类大小计算遵循结构体对齐原则
类的大小与数据成员有关与成员函数无关
类的大小与静态数据成员无关
虚继承对类的大小的影响
虚函数对类的大小的影响
在g++编译器下的情况
一、只出现虚继承的情况
从输出的地址和虚基类表成员数据可以画出对象内存模型图:
virtual base table
本类地址与虚基类表指针地址的差
虚基类地址与虚基类表指针地址的差
virtual base table pointer(vbptr)
从程序可以看出pp是BB* 指针,通过打印pp 的值与&dd 比较可知,
cout<<(void*)&dd<
从成员输出的地址和通过虚函数表指针访问到的函数可以画出模型:
DD::vfdd 的位置跟继承的顺序有关,如果DD先继承的是B2, 那么它将跟在B2::vfb2 的下面。
如果派生类是从多个基类继承或者有多个继承分支(从所有根类开始算起),而其中若干个继承分支上出现了多态类,则派生类将从这些分支中的每个分支上继承一个vptr,编译器也将为它生成多个vtable,有几个vptr就生成几个vtable(每个vptr分别指向其中一个),分别与它的多态基类对应。
三、虚继承与虚函数同时出现的情况:
对象内存模型图:
类大小计算遵循结构体对齐原则
类的大小与数据成员有关与成员函数无关
类的大小与静态数据成员无关
虚继承对类的大小的影响
虚函数对类的大小的影响
在g++编译器下的情况
一、只出现虚继承的情况
#include <iostream> using namespace std; class BB { public : int bb_ ; }; class B1 : virtual public BB { public : int b1_ ; }; class B2 : virtual public BB { public : int b2_ ; }; class DD : public B1, public B2 { public : int dd_ ; }; int main (void) { cout<<sizeof (BB)<< endl; cout<<sizeof (B1)<< endl; cout<<sizeof (DD)<< endl; return 0;
从输出的地址和虚基类表成员数据可以画出对象内存模型图:
virtual base table
本类地址与虚基类表指针地址的差
虚基类地址与虚基类表指针地址的差
virtual base table pointer(vbptr)
从程序可以看出pp是BB* 指针,通过打印pp 的值与&dd 比较可知,
cout<<(void*)&dd<
#include <iostream> using namespace std; class BB { public: virtual void vpbb() { cout << "BB:vpbb().." << endl; } int bb_; }; class B1 : public BB { public: virtual void vpb1() { cout << "B1:vpb1().." << endl; } int b1_; }; class B2 : public BB { public: virtual void vpb2() { cout << "B2:vpb2().." << endl; } int b2_; }; class DD : public B1, public B2 { public: virtual void vpdd() { cout << "DD:vpdd().." << endl; } int dd_; }; typedef void (* FUNC)(void ); int main() { cout << sizeof(BB) << endl; cout << sizeof(B1) << endl; cout << sizeof(DD) << endl; cout << endl; return 0; }
从成员输出的地址和通过虚函数表指针访问到的函数可以画出模型:
DD::vfdd 的位置跟继承的顺序有关,如果DD先继承的是B2, 那么它将跟在B2::vfb2 的下面。
如果派生类是从多个基类继承或者有多个继承分支(从所有根类开始算起),而其中若干个继承分支上出现了多态类,则派生类将从这些分支中的每个分支上继承一个vptr,编译器也将为它生成多个vtable,有几个vptr就生成几个vtable(每个vptr分别指向其中一个),分别与它的多态基类对应。
三、虚继承与虚函数同时出现的情况:
#include <iostream> using namespace std; class BB { public : virtual void vfbb() { cout<<"BB::vfbb" <<endl; } virtual void vfbb2() { cout<<"BB::vfbb2" <<endl; } int bb_ ; }; class B1 : virtual public BB { public : virtual void vfb1() { cout<<"B1::vfb1" <<endl; } int b1_ ; }; class B2 : virtual public BB { public : virtual void vfb2() { cout<<"B2::vfb2" <<endl; } int b2_ ; }; class DD : public B1, public B2 { public : virtual void vfdd() { cout<<"DD::vfdd" <<endl; } int dd_ ; }; typedef void (* FUNC)(void); int main (void) { cout<<sizeof (BB)<< endl; cout<<sizeof (B1)<< endl; cout<<sizeof (DD)<< endl; return 0; }
对象内存模型图:
相关文章推荐
- Data语意学之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- [置顶] 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- [置顶] 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- 三十二、C++内存布局,对象大小计算、虚函数虚继承对类内存模型的影响
- C++ 06 继承与组合 (has-a is-a) 以及类大小的计算 虚基类对内存模型的影响(不考虑虚函数)
- 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响
- C++ 虚继承和虚函数同时存在的对象模型
- C++虚函数、虚继承、对象内存模型
- C++虚函数、虚继承、对象内存模型(转)
- c++ 继承 33 虚继承对c++ 对象内存模型造成的影响
- 【C++】虚函数在不同继承方式中的对象模型
- 【深入探索c++对象模型】类对象所需内存大小讨论续写
- C++ 虚继承的对象模型
- 【c++】虚函数对对象大小的影响
- C++多重继承和虚拟继承对象模型、效率分析
- 深入探索c++虚函数继承模型
- C++研究笔记(6)存储模型和对象模型
- 虚继承内存布局@c++对象模型