zoukankan      html  css  js  c++  java
  • 一个类的实例化对象所占空间的大小(对象大小= vptr(可能不止一个) + 所有非静态数据成员大小 + Aligin字节大小(依赖于不同的编译器))

    注意不要说类的大小,是类的对象的大小.

    首先,类的大小是什么?确切的说,类只是一个类型定义,它是没有大小可言的。 
    用sizeof运算符对一个类型名操作,得到的是具有该类型实体的大小。 
    如果 
    Class A; 
    A obj; 
    那么sizeof(A)==sizeof(obj) 
    那么sizeof(A)的大小和成员的大小总和是什么关系呢,很简单,一个对象的大小大于等于所有非静态成员大小的总和。 
    为什么是大于等于而不是正好相等呢?超出的部分主要有以下两方面: 
    1) C++对象模型本身 
    对于具有虚函数的类型来说,需要有一个方法为它的实体提供类型信息(RTTI)和虚函数入口,常见的方法是建立一个虚函数入口表,这个表可为相同类型的对象共享,因此对象中需要有一个指向虚函数表的指针,此外,为了支持RTTI,许多编译器都把该类型信息放在虚函数表中。但是,是否必须采用这种实现方法,C++标准没有规定,但是这几户是主流编译器均采用的一种方案。 
    2) 编译器优化 
    因为对于大多数CPU来说,CPU字长的整数倍操作起来更快,因此对于这些成员加起来如果不够这个整数倍,有可能编译器会插入多余的内容凑足这个整数倍,此外,有时候相邻的成员之间也有可能因为这个目的被插入空白,这个叫做“补齐”(padding)。所以,C++标准紧紧规定成员的排列按照类定义的顺序,但是不要求在存储器中是紧密排列的。 
    基于上述两点,可以说用sizeof对类名操作,得到的结果是该类的对象在存储器中所占据的字节大小,由于静态成员变量不在对象中存储,因此这个结果等于各非静态数据成员(不包括成员函数)的总和加上编译器额外增加的字节。后者依赖于不同的编译器实现,C++标准对此不做任何保证。

    C++标准规定类的大小不为0,空类的大小为1,当类不包含虚函数和非静态数据成员时,其对象大小也为1。

    如果在类中声明了虚函数(不管是1个还是多个),那么在实例化对象时,编译器会自动在对象里安插一个指针指向虚函数表VTable,在32位机器上,一个对象会增加4个字节来存储此指针,它是实现面向对象中多态的关键。而虚函数本身和其他成员函数一样,是不占用对象的空间的。

    我们来看下面一个例子:(此例子在Visual C++编译器中编译运行)

    #include <iostream>
    using namespace std;
    class   A  
    {  
    };  
    class   B  
    {  
    char   ch;  
    void   func()  
    {  
    }  
    };  
    class   C  
    {  
    char   ch1;    //占用1字节
    char   ch2;   //占用1字节
    virtual   void   func()  
    {  
    }  
    };  
    class   D  
    {  
    int   in;  
    virtual   void   func()  
    {  
    }  
    };  
    void   main()  
    {  
    A   a;
    B   b;
    C   c;
    D   d;
    cout<<sizeof(a)<<endl;//result=1  
    cout<<sizeof(b)<<endl;//result=1   //对象c扩充为2个字,但是对象b为什么没扩充为1个字呢?大家帮忙解决
    cout<<sizeof(c)<<endl;//result=8  
    //对象c实际上只有6字节有用数据,但是按照上面第二点编译器优化,编译器将此扩展为两个字,即8字节
    cout<<sizeof(d)<<endl;//result=8  

      

    综上所述:

    一个类中,虚函数、成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空间的。

    对象大小=   vptr(可能不止一个)   +   所有非静态数据成员大小   +   Aligin字节大小(依赖于不同的编译器)

    #include <iostream>
    using namespace std;
     
    class demo1{
     
    };
     
    class demo2{
        static int num;
    };
     
    class demo3{
        virtual int print(){}
        virtual int print1(){}
    };
     
    class demo4{
     
        void print(){}
        static void print1(){}
    };
     
    class demo5{
        char a;
    };
     
    int _tmain(int argc, _TCHAR* argv[])
    {  
        cout<<"空类的大小为:"<<sizeof(demo1)<<endl;
        //当类不包含虚函数和非静态数据成员时,其对象大小也为1。
        cout<<"当类不包含虚函数和非静态数据成员时,其对象大小也为:"<<sizeof(demo2)<<endl;
     
        cout<<"与类中虚函数的个数无关"<<sizeof(demo3)<<endl;    //大小是4,与类中虚函数的个数无关,
        cout<<"成员函数(静态和非静态)也不占用类对象的存储空间"<<sizeof(demo4)<<endl;
        cout<<sizeof(demo5)<<endl;
        demo5 d;
        cout<<sizeof(d)<<endl;
        return 0;
    }

      

    http://www.cnblogs.com/rollenholt/archive/2012/03/28/2421871.html

  • 相关阅读:
    hdu 5366 简单递推
    hdu 5365 判断正方形
    hdu 3635 并查集
    hdu 4497 数论
    hdu5419 Victor and Toys
    hdu5426 Rikka with Game
    poj2074 Line of Sight
    hdu5425 Rikka with Tree II
    hdu5424 Rikka with Graph II
    poj1009 Edge Detection
  • 原文地址:https://www.cnblogs.com/findumars/p/6375488.html
Copyright © 2011-2022 走看看