sizeof 详解 类大小计算
空类的大小为1字节
一个类中,虚函数本身、成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空间。
对于包含虚函数的类,不管有多少个虚函数,只有一个虚指针,vptr的大小。
普通继承,派生类继承了所有基类的函数与成员,要按照字节对齐来计算大小
虚函数继承,不管是单继承还是多继承,都是继承了基类的vptr。(32位操作系统4字节,64位操作系统 8字节)!
虚继承,继承基类的vptr。
原则1 空类的大小为1字节
1 2 3 4 5 6 7 8 9 10 11 #include <iostream> using namespace std;class A {};int main () { cout << sizeof (A) << endl; return 0 ; }
原则2 静态数据成员被编译器放在程序的一个global data members中,它是类的一个数据成员,但不影响类的大小。不管这个类产生了多少个实例,还是派生了多少新的类,静态数据成员只有一个实例。静态数据成员,一旦被声明,就已经存在。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <iostream> using namespace std;class A {public : char b; virtual void fun () {}; static int c; static int d; static int f; }; int main () { cout << sizeof (A) << endl; return 0 ; }
原则3 对于包含虚函数的类,不管有多少个虚函数,只有一个虚指针,vptr的大小。
1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> using namespace std;class A { virtual void fun () ; virtual void fun1 () ; virtual void fun2 () ; virtual void fun3 () ; }; int main () { cout << sizeof (A) << endl; return 0 ; }
原则4与5
普通单继承,继承就是基类+派生类自身的大小(注意字节对齐)。注意:类的数据成员按其声明顺序加入内存,无访问权限无关,只看声明顺序。
虚单继承,派生类继承基类vptr
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include <iostream> using namespace std;class A {public : char a; int b; }; class B : A {public : short a; long b; }; class C { A a; char c; }; class A1 { virtual void fun () {} }; class B1 : public A1 {};class A2 { virtual void funA () {} }; class B2 { virtual void funB () {} }; class C2 : public A2, public B2 {};int main () { cout << sizeof (A) << endl; cout << sizeof (B) << endl; cout << sizeof (C) << endl; cout << sizeof (B1) << endl; cout << sizeof (C2) << endl; return 0 ; }
原则6 虚继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> using namespace std;class A { virtual void fun () {} }; class B { virtual void fun2 () {} }; class C : virtual public A, virtual public B {public : virtual void fun3 () {} }; int main () { cout << sizeof (A) << " " << sizeof (B) << " " << sizeof (C); return 0 ; }