Determining the Size of a Class Object

Determining the Size of a Class Object

转自:http://cprogramming.com/tutorial/size_of_class_object.html

By Girish Shetty

There are many factors that decide the size of an object of a class in C++. These factors are:

  1. Size of all non-static data members
  2. Order of data members
  3. Byte alignment or byte padding
  4. Size of its immediate base class
  5. The existence of virtual function(s) (Dynamic polymorphism using virtual functions).
  6. Compiler being used
  7. Mode of inheritance (virtual inheritance)

Size of all non-static data members

Only non-static data members will be counted for calculating sizeof class/object.

class A { 
private: 
        float iMem1; 
        const int iMem2; 
        static int iMem3; 
        char iMem4; 
}; 

For an object of class A, the size will be the size of float iMem1 + size of int iMem2 + size of char iMem3. Static members are really not part of the class object. They won't be included in object's layout. <2>Order of data members

 

The order in which one specifies data members also alters the size of the class.

class C { 
        char c; 
        int int1; 
        int int2; 
        int i; 
        long l; 
        short s; 
}; 

The size of this class is 24 bytes. Even though char c will consume only 1 byte, 4 bytes will be allocated for it, and the remaining 3 bytes will be wasted (holes). This is because the next member is an int, which takes 4 bytes. If we don't go to the next (4th) byte for storing this integer member, the memory access/modify cycle for this integer will be 2 read cycles. So the compiler will do this for us, unless we specify some byte padding/packing.

If I re-write the above class in different order, keeping all my data members like below:

class C { 
        int int1; 
        int int2; 
        int i; 
        long l; 
        short s; 
        char c; 
}; 

Now the size of this class is 20 bytes.

In this case, it is storing c, the char, in one of the slots in the hole in the extra four bytes.

Byte alignment or byte padding

As mentioned above, if we specify 1 byte alignment, the size of the class above (class C) will be 19 in both cases.

Size of its immediate base class

The size of a class also includes size of its immediate base class.

Lets take an example:

Class B { 
... 
        int iMem1; 
        int iMem2; 
} 

Class D: public B { 
... 
        int iMem; 
} 

In this case, sizeof(D) is will also include the size of B. So it will be 12 bytes.

The existence of virtual function(s)

Existence of virtual function(s) will add 4 bytes of virtual table pointer in the class, which will be added to size of class. Again, in this case, if the base class of the class already has virtual function(s) either directly or through its base class, then this additional virtual function won't add anything to the size of the class. Virtual table pointer will be common across the class hierarchy. That is

class Base { 
public: 
... 
        virtual void SomeFunction(...); 
private: 
        int iAMem 
}; 

class Derived : public Base { 
... 
        virtual void SomeOtherFunction(...); 
private: 
        int iBMem 
}; 

In the example above, sizeof(Base) will be 8 bytes--that is sizeof(int iAMem) + sizeof(vptr). sizeof(Derived) will be 12 bytes, that is sizeof(int iBMem) + sizeof(Derived). Notice that the existence of virtual functions in class Derived won't add anything more. Now Derived will set the vptr to its own virtual function table.

Compiler being used

In some scenarios, the size of a class object can be compiler specific. Lets take one example:

class BaseClass { 
        int a; 
        char c; 
}; 

class DerivedClass : public BaseClass { 
        char d; 
        int i; 
}; 

If compiled with the Microsoft C++ compiler, the size of DerivedClass is 16 bytes. If compiled with gcc (either c++ or g++), size of DerivedClass is 12 bytes.

The reason for sizeof(DerivedClass) being 16 bytes in MC++ is that it starts each class with a 4 byte aligned address so that accessing the member of that class will be easy (again, the memory read/write cycle).

Mode of inheritance (virtual inheritance)

In C++, sometimes we have to use virtual inheritance for some reasons. (One classic example is the implementation of final class in C++.) When we use virtual inheritance, there will be the overhead of 4 bytes for a virtual base class pointer in that class.

class ABase{ 
        int iMem; 
}; 

class BBase : public virtual ABase { 
        int iMem; 
}; 

class CBase : public virtual ABase { 
        int iMem; 
}; 

class ABCDerived : public BBase, public CBase { 
        int iMem; 
}; 

And if you check the size of these classes, it will be:

  • Size of ABase : 4
  • Size of BBase : 12
  • Size of CBase : 12
  • Size of ABCDerived : 24

Because BBase and CBase are dervied from ABase virtually, they will also have an virtual base pointer. So, 4 bytes will be added to the size of the class (BBase and CBase). That is sizeof ABase + size of int + sizeof Virtual Base pointer.

Size of ABCDerived will be 24 (not 28 = sizeof (BBase + CBase + int member)) because it will maintain only one Virtual Base pointer (Same way of maintaining virtual table pointer).

基于STM32设计的数字示波器全套资料(原理图、PCB图、源代码) 硬件平台: 主控器:STM32F103ZET6 64K RAM 512K ROM 屏幕器:SSD1963 分辨率:480*272 16位色 触摸屏:TSC2046 模拟电路: OP-TL084 OP-U741 SW-CD4051 CMP-LM311 PWR-LM7805 -LM7905 -MC34063 -AMS1117-3.3 DRT-ULN2003 6.继电器:信号继电器 7.电源:DC +12V 软件平台: 开发环境:RealView MDK-ARM uVision4.10 C编译器:ARMCC ASM编译器:ARMASM 连机器:ARMLINK 实时内核:UC/OS-II 2.9实时操作系统 GUI内核:uC/GUI 3.9图形用户接口 底层驱动:各个外设驱动程序 数字示波器功能: 波形发生器:使用STM32一路DA实现正弦,三角波,方波,白噪声输出。 任意一种波形幅值在0-3.3V任意可调、频率在一定范围任意可调、方波占空比可调。调节选项可以通过触摸屏完成设置。 SD卡存储: SD卡波形存储输出,能够对当前屏幕截屏,以JPG格式存储在SD卡上。能够存储1S内的波形数据,可以随时调用查看。 数据传输:用C#编写上位机,通过串口完成对下位机的控制。(1)实现STOP/RUN功能(2)输出波形电压、时间参数(3)控制截屏(4)控制波形发生器(5)控制完成FFT(6)波形的存储和显示 图形接口: UCGUI 水平扫速: 250 ns*、500ns、1μs、5 μs、10μs、50μs、500 μs、5ms 、50ms 垂直电压灵敏度:10mV/div, 20mV/div, 50mV/div, 0.1V/div, 0,2V/div, 0.5V/div, 1V/div,2V/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值