注意内存对齐
struct Stu
{int id;char sex;float hight;
};
cout<<sizeof(Stu)<<endl; 会输出什么?
字节对齐原则:在系统默认的对齐方式下:每个成员相对于这个结构体变量地址的偏移量正好是该成员类型所占字节的整数倍,且最终占用字节数为成员类型中最大占用字节数的整数倍。
struct A {char y;char z;long long x;
}; 16字节
struct A {char y;char z;int x;
}; 8字节struct A {char y;char* z;int x;
};12字节
struct A {char y;
}; 1字节
最终大小一定是最大数据类型的整数倍;
静态变量不占空间
每种类型的偏移量为自身的n倍;
虚函数
类的大小为类的非静态成员数据的类型大小之和**,也就是说静态成员数据不作考虑。
普通成员函数与sizeof无关。
虚函数由于要维护在虚函数表,所以要占据一个指针大小,也就是4字节。
#include <iostream>
using namespace std;class Base
{
private:char a;
public:virtual void f();virtual void g();
};
class Derived:public Base
{
private:int b;
public:void f();
};
class Derived1:public Base
{
private:double b;
public:void g();virtual void h();
};int main(int argc, char** argv) {cout << sizeof(Base) << endl;cout << sizeof(Derived) << endl;cout << sizeof(Derived1) << endl;return 0;
}
结果为16,16,24
Base类:
vfptr是虚函数表指针,只要含虚函数,一定有虚函数表指针,而且该指针一定位于类内存模型最前端,接下来是Base类的成员变量,char a,如下图:
Derived类:
最一开始的还是虚函数表指针,只不过,在Derived类中被重写的虚函数f()在对应的虚函数表项的Base::f()已经被替换为Derived::f(),接下来是基类的成员变量char a,紧接着是继承类的成员变量int b,如图:
Derived1类:
Derived1类一开始仍然是虚函数表指针,只是在Derived1类中被重写的虚函数g()在对应的虚函数表项的Base::g()已经被替换为Derived1::g(),新添加的虚函数virtual h()位于虚函数表项的后面,紧跟着基类中最后声明的虚函数表项后,接下来仍然是基类的成员变量 char a,紧接着是类的成员变量double b。
更多的可以参考这篇文章
C++类大小详尽讲解_c++ 类的大小_StudyWinter的博客-CSDN博客