C++中对象的大小

来源:互联网 发布:java成神之路 编辑:程序博客网 时间:2024/06/05 08:55

C++中对象的大小

需要多少内存才能表现一个class object?一般而言要有:

n  nonstatic data members的总和大小;

n  加上任何由于字节对齐需要而填充上去的空间(可能存在与members之间,也可能存在于集合体边界);

n  加上为了支持virtual而由内部产生的任何额外负担。

 

C++中实际对象的大小,不同编译器的实现是不一样的,以下仅讨论.net2008,其他编译的可能出现的结果以下也做了分析和猜测。在反推不同编译器实现的C++对象的大小时,对齐是一个很重要也容易被遗忘的问题。

 

class A{};

看上去一个空的类A事实上并不是空的,它有一个隐含的1byte,那是被编译器安插进去的一个char,这使得这个class的两个objects得以在内存中配置独一无二的地址:

A ab

If ( &a == &b ) cerr<<yipes!<<endl;

 

class B:public virtual A{};

B类是对A类的虚继承,B中一般会有指向A的实例的指针,在IA-32下为4bytes。这里不同编译器的实现差别很大,有的编译器在B的对象中也会保留A类的那个隐含的char,于是就有1+4=5bytes,再考虑对齐,有些编译器产生的结果为8bytes,但是在.net2008中优化过了,不会有A中的char,也就不需要对齐,只有4bytes大小

class C:public virtual A{};

同上

 

class D:public B,public C{};

D8,如果编译器不优化A中的char就会有1(A)+8(B)+8(C)-4(BA虚继承)-4(CA虚继承)+3(对齐)=12bytes

 

class E
{
     int i;
};

很明显4bytes

 

class F
{
     double d;
};

很明显8bytes

 

class G
{
     double num;
     char in;  
};

8bytes对齐,所以是8(double)+4(int)+4(对齐)=16

 

class H
{
     int num; 
     double in; 
};

同上

 

class I
{
      int num; 

      double in;    

public:
      virtual ~I(){};
};

8(double)+4(int)+4(对齐)+4(vptr)+4(对齐)=24


class J
{
     double num; 
     int in;    
public:
     virtual ~J(){};
};

同上8(double)+4(int)+4(对齐)+4(vptr)+4(对齐)=24


class K
{
     int i;
     int k;
public:
     virtual ~K(){};
};

4(int)+4(int)+4(vptr)=12


class L
{
    int i;
    int j;
    L(){};
 public:
     float ll(int i)
     {
         return 0.0;
     }
     static int hhh(int i)
    {
        return 0.0;
    }
    virtual ~L(){};
    virtual ji(){};
};

虚函数表的指针vptr,只有类中出现虚函数才会出现,它指向虚函数表,所有虚函数的地址存放在此表中。4(int)+4(int)+4(vptr)=12从中看出,不管有多少虚函数,大小不变,因为类中只保存虚函数表。不管成员函数有多少,类大小也不变,因为他们不保存在对象中,无论是否是静态。

#include <iostream>

using std::cout;

using std::endl;

 

class A{};

class B:public virtual A{};

class C:public virtual A{};

class D:public B,public C{};

 

class E

{

     int i;

};

 

class F

{

     double d;

};

 

class G

{

     double num;

     char in;  

};

 

class H

{

     int num;

     double in;   

};

 

class I

{

      int num;

      double in;    

public:

      virtual ~I(){};

};

 

class J

{

     double num;

     int in;    

public:

     virtual ~J(){};

};

 

class K

{

     int i;

     int k;

public:

     virtual ~K(){};

};

 

class L

{

      int i;

      int j;

      L(){};

public:

 float ll(int i)

 {

         return 0.0;

     }

     static double hhh(int i)

 {

         return 0.0;

 }

 virtual ~L(){};

 virtual void ji(){};

};

 

int main()

{

    cout <<"A "<<sizeof(A)<<endl;

    cout <<"B "<<sizeof(B)<<endl;

    cout <<"C "<<sizeof(C)<<endl;

    cout <<"D "<<sizeof(D)<<endl;

    cout <<"E "<<sizeof(E)<<endl;

    cout <<"F "<<sizeof(F)<<endl;

    cout <<"G "<<sizeof(G)<<endl;

    cout <<"H "<<sizeof(H)<<endl;

    cout <<"I "<<sizeof(I)<<endl;

    cout <<"J "<<sizeof(J)<<endl;

    cout <<"K "<<sizeof(K)<<endl;

    cout <<"L "<<sizeof(L)<<endl;

 }

 

/*******************************************************************/

输出结果为:

A 1

B 4

C 4

D 8

E 4

F 8

G 16

H 16

I 24

J 24

K 12

L 12

/*******************************************************************/

 

 

 

参考资料:

《深度探索 C++对象模型》P83~88

http://blog.csdn.net/zzm7000/archive/2006/03/30/644467.aspx

原创粉丝点击