一:单个类带虚函数的数据成员布局
#include <iostream> using namespace std; class A { public: int m_i=0; int m_j = 0; public: virtual void fun(){ } }; int main() { A a; cout<<sizeof(a)<<endl; printf("A::m_i = %d\n", &A::m_i);//打印偏移量地址 printf("A::m_j = %d\n", &A::m_j); a.m_i = 2; //断点在这一行 a.m_j = 4; return 0; }结果表明:虚函数表指针在对象内存布局的最前面,->m_i,->m_j。
验证: 二:单一继承父类带虚函数的数据成员布局
#include <iostream> using namespace std; class base { public: virtual void my() {} int m_bi; }; class A :public base { public: int m_i=0; int m_j = 0; public: virtual void fun(){ } }; int main() { A a; cout<<sizeof(a)<<endl; printf("A::m_i = %d\n", &A::m_bi); printf("A::m_i = %d\n", &A::m_i); printf("A::m_j = %d\n", &A::m_j); a.m_bi = 3; a.m_i = 2; a.m_j = 4; return 0; }结果表明了各个变量在对象a的内存模型里的布局。 虚函数表指针指向虚函数表,虚函数表里存放着子类和父类各自的虚函数。
验证:
三:单一继承父类不带虚函数的数据成员布局。
#include <iostream> using namespace std; class base { public: int m_bi; }; class A :public base { public: int m_i=0; int m_j = 0; public: virtual void fun(){ } }; int main() { A a; cout<<sizeof(a)<<endl; printf("A::m_i = %d\n", &A::m_bi); printf("A::m_i = %d\n", &A::m_i); printf("A::m_j = %d\n", &A::m_j); a.m_bi = 3; a.m_i = 2; a.m_j = 4; return 0; }从结果来看,难道m_i在对象布局的最前面? 其实不是,因为在父类没有虚函数的情况下,m_i是对于父类的偏移量,所以是0。
其实,二和三的情况,,对象布局是一样的。
验证: 从图来看,03 00 00 00并不是在最前面,所以说二和三的对象内存布局是一样的。