C++sizeof使用规则及陷阱分析五
来源:优易学  2011-11-9 14:25:41   【优易学:中国教育考试门户网】   资料下载   IT书店

  类class中的sizeof特别探讨

  写在前面,本节假设你看过《Inside the C++ Object Model》,如果没有,最好了解类与对象在内存中map问题

  这里引用《Inside the C++ Object Model》中的对象模型的内存镜像图:

  (一)不考虑继承关系(单继承、多继承、虚继承等)

  (1)不带virtual函数时

  空类:

  1 class A

  2 {

  3

  4 };

  5

  6 cout << sizeof(A) << endl; // 1

  空类总是返回1

  1 class B {

  2 private :

  3 int value;

  4 double a;

  5 public:

  6

  7 };

  8

  9 cout << sizeof(B) << endl; //16

  10

  和struct一样,也要考虑对齐问题,以及成员的顺序因为成员函数不会分配空间,所以sizeof时只计算数据成员的大小

  (2)带virtual函数时

  单继承情况下,只要class中存在virtual函数,编译器在编译时就会自动插入一个指向虚函数表的指针vptr(大小为4字节). 不同的编译器vptr插入的位置可能不同,VC编译器插入vptr的位置一般是数据成员开始。

  下例在MinGW Develper Studio2.05(gcc)下编译,VC 6.0编译器下结果为24  24, 我不太理解为什么...

  1 class A

  2 {

  3 public:

  4 virtual void foo() {}

  5 private:

  6 int m1;

  7 double m2;

  8 };

  9

  10 class B

  11 {

  12 public:

  13 virtual void foo() {}

  14 private:

  15 double m2;

  16 int m1;

  17 };

  18

  19

  20 cout << sizeof(A) << endl; // 16

  21 cout << sizeof(B) << endl; // 24

 (3)带static成员时

  1 class A {

  2 private :

  3 int value;

  4 double a;

  5 static int CST;

  6 public:

  7 };

  8

  9 cout << sizeof(A) << endl; //16

  因为static成员是分配在全局区为类的所有对象共享(VC编译器可能为了方便将其放入文字常量表), sizeof时不应该计入sttic成员

  (二)继承关系下

  (1)单继承情况下

  总体上讲, 派生类中需要考虑基类子类型(subtype)的问题,派生对象要考虑基类子对象的问题。

  1 class A

  2 {

  3 public:

  4

  5 private:

  6 int m1;

  7 double m2;

  8 };

  9

  10 class B : public A

  11 {

  12 public:

  13

  14 private:

  15 int m3;

  16 };

  17

  18 cout << sizeof(A) << endl; // 16

  19 cout << sizeof(B) << endl; // 24

  20

  同样,要考虑陷阱:基类对齐字节不等于大小,如下例:

  1 class A

  2 {

  3 public:

  4

  5 private:

  6 char m1[8];

  7

  8 };

  9

  10 class B : public A

  11 {

  12 public:

  13

  14 private:

  15 char m3;

  16 };

  17

  18 cout << sizeof(A) << endl; // 8

  19 cout << sizeof(B) << endl; // 9

  20

  21

  1 class A

  2 {

  3 public:

  4

  5 private:

  6 char m1[9];

  7

  8 };

  9

  10 class B : public A

  11 {

  12 public:

  13

  14 private:

  15 int m3;

  16 };

  17

  18 cout << sizeof(A) << endl; // 9

  19 cout << sizeof(B) << endl; // 16

  20

  21

  同样道理,如果一直继承下去,考虑的问题同上。有虚函数不要忘记vptr指针。

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训