C++类的存储(部分可用与c的结构体)

c++中最重要的就是类,那么给你一个类的对象,你知道它在内存中如何存储的吗?它占内存中多少个字节?


首先确定类的构成:
1,数据成员:可以是内置类型,类类型。
2,函数成员:虚函数,非虚函数。


1)数据成员

内置类型对齐原则
内置类型就是常用的:char,short,long,int,float,double.
这些内置类型在类的对象中对齐方式,字节为单位(在 c 中结构体也是一样的)
char          1
short         2
long          4
int           4
float         4
fouble        8
类类型对齐原则(c中就是结构体对齐原则)
取类中最长的数据成员作为对齐原则。例如,类中最长为 double,那么就是 8个字节。


2)函数成员

函数成员是不占用内存中类的对象的字节。为什么呢,你可以这样理解,c++中为了兼容c也允许 struct 作为类的声明。在 c 中 struct 是用来声明结构体类型的,只不过 c 中的结构体没有函数成员。 同样 c++中允许的函数成员,只不过是类给函数提供了一个作用域。
一个对象调用函数的时候,可以等价为普通函数的调用
例如:
struct A
{
void f(){cout<<x<<endl;};

int x;

};
A a;
a.f();
a.f()等价于调用 f(&a);类中的成员函数(static 成员函数除外)形参中都有个隐含的 this指针,它指向类对象本身。
当对象 a 调用 f()的时候,它会把 a 的地址传给 this 指针,所以 f()就等价执行
f(const A* this)
{
cout<<this->x<<endl;
}
所以对象中并不需要保存函数成员。
下面举个例子说明类对象的字节数
1,
class A
{
    char c;
    int i;
};
A a;
这对象 a 的内存大小 sizeof(a)=8(字节为单位)
解释下:
c 放在起始位置 0,占 1个字节。 i 是 int 要 4字节对齐,所以前面要空 3字节。它要从位置 4开始存储,占 4,5,6,7 四个位置。
最后类要按照他最长的数据成员对齐, 就是 i 也就是 4字节对齐.因为已经占用了 8个字节,
8是对齐 4的,所以不用额外增加字节数了。最后 sizeof(a)=8。
2,
class B
{
    doube d;
    char c;
    A a;//1中的类类型 A
};
B b;
这对象 b 的内存大小 sizeof(b)=24(字节为单位)
解释:
d 放在起始位置 0到 7,占 8个字节。
c 是 char 要1字节对齐,所以放在位置 8,占 1个字节。
b 是类类型,在 1中可以知道它是 8字节对齐的,所以前面要空 7个字节,它从位置 16开始存储,一直到 23,占 8个字节。
最后类要按照他最长的数据成员对齐,就是 d 也就是 8字节对齐,因为已经占用了 24个字节,24是对齐 8的,所以不用额外增加字节数了。最后 sizeof(a)=24。
3,
class c
{
    char c;
    int i1;
    double d;
    int i2;
};
C c;
你知道 sizeof(c)=多少吗? 答案:24.不解释了~。(注意这个最后需要额外增加空间来
对齐类)
上面讲的,你同样可以使用 c 中的结构体类型变量的字节数计算。


下面说下特殊的,就是 c 中没有的。
1,类中有虚函数的时候
我们在一开始的时候,就说了成员函数中有虚函数。c++为了处理多态,所以引入虚函数。
在一个类对象存储空间中,第一个位置需要 4个字节来存储一个指针。这个指针是指向改类的虚函数表的。也就是这个指针的值就是改类的虚函数表的地址。所以就比上面说的多了4个字节。
例如:
class D
{
public:
    virtual void f(){};
    double d;
}
D d;
sizeof(d)=16;
2,派生类内存大小
例如:
class E:D {
    int d0;
    char c;
    int d1;
};
E e;
sizeof(e)=32;
解释:
基类中有虚函数,所以派生类对象一开始要 4个字节存储指向虚函数表的指针。
然后继承 D中的数据成员 double d;
它要 8字节对齐,所以前面空 4个字节。
下面就开始存储 d0,c,d1.最后类对齐可计算得到 32.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值