matlab sizeof size,sizeof(class) 分析

C++中类对象的大小由多个因素决定,包括非静态数据成员的大小、成员顺序、字节对齐、基类大小、虚函数的存在以及使用的编译器。非静态成员、基类大小和虚函数都会增加对象的大小,而字节对齐可能导致内存空洞。虚继承会引入虚基类指针,每个类仅有一个虚函数表,虚函数不会重复增加大小。编译器的选择也可能影响对象大小,例如在不同编译器下,对象布局可能有所不同。
摘要由CSDN通过智能技术生成

Determining the Size of a Class Object

By Girish Shetty

There are many factors that decide the size of an object of a class

in C++. These factors are:

Size of all non-static data

members //静态数据成员的大小

Order of data

members //数据成员的顺序

Byte alignment or byte

padding //字节校正、对齐

Size of its immediate base

class //基类的大小

The existence of virtual function(s) (Dynamic polymorphism

using virtual functions). //是否存在虚函数

Compiler being

used 使用的编译器

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).

大小为24,因为它只有一个虚基类指针;

分析:

以上都经过验证,一定正确,但是还有一些值得注意的问题,主要是两个,一个是虚函数、一个是虚继承;

1. 通常情况下,虚函数的一搬继承中,不在计算基类中虚函数的大小,以为一个类中只有一个虚函数表;

2.

虚继承相对就比较复杂一些,虚继承中的问题主要是,当前基类的大小,加上现在类的大小,同时还要加上一个虚指针,这个虚指针式指向虚函数的,所以相当于额外加上4,但是还要遵循第一个的条件,一个函数中只能有一个虚指针,一个虚指针表,所以在计算时要注意,每一个函数都只有一个自己的虚指针!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值