类大小sizeof(class)

class如同int等内建类型一样,分配有一定大小的内存,本文通过基本类、含有虚函数的类、单继承的派生类和多重继承的派生类来考察类的内存布局规律。

1、普通类对象的大小

[cpp:firstline[1]] view plain copy print ?
  1. //普通类对象的内存布局
  2. struct C000
  3. {
  4. };
  5. struct C001
  6. {
  7. C001() : c_(0x01) {}
  8. char c_;
  9. };
  10. struct C010
  11. {
  12. C010() : c1_(0x01),c2_(0x02) {}
  13. char c1_;
  14. char c2_;
  15. };
  16. struct C011
  17. {
  18. C011() : c1_(0x01),c2_(0x02) {}
  19. void foo() { c1_ = 0x02; }
  20. char c1_;
  21. char c2_;
  22. };
  23. struct C100
  24. {
  25. C100() : c1_(0x01),c2_(0x02) {}
  26. void foo() { c1_ = 0x02; }
  27. char c1_;
  28. char c2_;
  29. static char sc1_;
  30. static void sfoo(){sc1_=0x02;}
  31. };
  32. void test_single_class()
  33. {
  34. cout<<"sizeof(struct C000)="<<sizeof(struct C000)<<endl;//1
  35. cout<<"sizeof(struct C001)="<<sizeof(struct C001)<<endl;//1
  36. cout<<"sizeof(struct C010)="<<sizeof(struct C010)<<endl;//2
  37. cout<<"sizeof(struct C011)="<<sizeof(struct C011)<<endl;//2
  38. cout<<"sizeof(struct C100)="<<sizeof(struct C100)<<endl;//2
  39. }

sizeof(struct C000)本应该是0,但有一个占位符;

普通成员函数,静态成员函数,及静态成员变量皆不会在类的对象中有所表示。其中普通成员函数是在编译期通过this指针与类关联的,静态成员函数和静态成员变量相当于全局变量,只不过比其多一个类名称的限定。

2、普通派生类对象的大小

[cpp:firstline[1]] view plain copy print ?
  1. //普通继承类对象的内存布局
  2. struct B010
  3. {
  4. B010() : c_(0x01) {}
  5. void foo() { c_ = 0x02; }
  6. private:
  7. char c_;
  8. };
  9. struct B011
  10. {
  11. B011() : c_(0x02), c2_(0x03) {}
  12. char c_;//这里的c_与B010同名也没影响
  13. char c2_;
  14. };
  15. struct B014 : private B011//这里的继承方式也没影响
  16. {
  17. };
  18. struct B015 : public B010,private B011
  19. {
  20. };
  21. void test_derive_class()//继承方式没有影响,即使有父子类有相同的成员变量,子类大小也不受影响
  22. {
  23. cout<<"=============================================="<<endl;
  24. cout<<"sizeof(struct B010)="<<sizeof(struct B010)<<endl;//1
  25. cout<<"sizeof(struct B011)="<<sizeof(struct B011)<<endl;//2
  26. cout<<"sizeof(struct B014)="<<sizeof(struct B014)<<endl;//2
  27. cout<<"sizeof(struct B015)="<<sizeof(struct B015)<<endl;//3
  28. }

可以理解为全盘继承下来,而不用管是否重名以及继承方式,两个父类有重名的成员,则在向上调用父类成员时就会产生向上二义性。

3、带虚函数类对象的大小

[cpp:firstline[1]] view plain copy print ?
  1. //带虚函数的对象的内存布局
  2. struct A001
  3. {
  4. virtual void foo(){}
  5. };
  6. struct A010:A001
  7. {
  8. virtual void foo1(){}
  9. };
  10. struct A011
  11. {
  12. virtual void foo1(){}
  13. virtual void foo2(){}
  14. };
  15. struct A100 : A011
  16. {
  17. virtual void foo3(){}
  18. };
  19. void test_virtual_class()
  20. {
  21. cout<<"========================================="<<endl;
  22. cout<<"sizeof(strcut A001)="<<sizeof(struct A001)<<endl;//4
  23. cout<<"sizeof(struct A010)="<<sizeof(struct A010)<<endl;//4
  24. cout<<"sizeof(struct A011)="<<sizeof(struct A011)<<endl;//4
  25. cout<<"sizeof(struct A100)="<<sizeof(struct A100)<<endl;//4
  26. }

带虚函数的类不同于普通类的是有一个虚函数表指针,也就是一个指针数组,而sizeof(*)为4.单继承派生类与基类共用一个虚函数表,但表的条目可能不一样,可能派生类虚函数表的条目多一些,或者是进行了改写。

4、带虚函数多重派生类对象大小

[c-sharp] view plain copy print ?
  1. //带虚函数多重继承类的内存布局
  2. struct D041
  3. {
  4. D041() : c_(0x01) {}
  5. virtual void foo() { }
  6. char c_;
  7. };
  8. struct D042
  9. {
  10. D042() : c_(0x02) {}
  11. virtual void foo2() {}
  12. char c_;
  13. };
  14. struct D051 : public D041,public D042
  15. {
  16. };
  17. struct D082 : public D041,public D042
  18. {
  19. D082() : c_(0x03) {}
  20. virtual void foo() {}
  21. virtual void foo2() {}
  22. virtual void foo3() {}
  23. char c_;
  24. };
  25. void test_virtual_multiple()
  26. {
  27. cout<<"========================================="<<endl;
  28. cout<<"sizeof(strcut D041)="<<sizeof(struct D041)<<endl;//5
  29. cout<<"sizeof(struct D042)="<<sizeof(struct D042)<<endl;//5
  30. cout<<"sizeof(struct D051)="<<sizeof(struct D051)<<endl;//10
  31. cout<<"sizeof(struct C082)="<<sizeof(struct D082)<<endl;//11
  32. }

含虚函数类多继承派生类拥有多个虚函数表,派生类可以重写各个基类的虚函数,从而修改了虚函数表,也可以添加虚函数,这个添加的虚函数指针条目将添加到第一个虚函数表中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值