C++类对象内存大小的计算?static的member function在内存的哪里

时间:2018-02-10 07:40:02   浏览:次   点击:次   作者:   来源:   立即下载

class Point{nprivate:n short count;ntint x,y;npublic:ntPoint(int xx, int yy):x(xx),y(yy),count(⓪){};nt~Point(){};ntint getX(){return x;};ntint getY(){return y;};ntstatic string getInfo(){return "this is a String";}n};n上述的Point对象大小是sizeof(Point)=①② · 很好理解, count(short)内存对齐占④个bytes(单位已改正, 谢vczh提醒), x, y各占④个bytes, 于是①共①②个bytes。

class Point{nprivate:ntshort count;ntint x,y;npublic:ntPoint(int xx, int yy):x(xx),y(yy),count(⓪){};ntvirtual ~Point(){};ntint getX(){return x;};ntint getY(){return y;};ntstatic string getInfo(){return "this is a String";}n};n当我把析构变为虚的之后, 大小变为了②④个bytes, 我能理解这是内存按最大单位长度(指针的⑧bits)对齐后的结果。

但我不理解这②④个bytes是怎么分配的, 既然要对齐, 为什么不是 ④*⑧=③②个bytes?

ps, 顺问问题②, 这样的内存对齐的好处到底是什么?

对于struct(class也归为此类)和union类型的变量,其成员是按照声明的顺序进行存储的。

默认情况下,字节对齐的规约是:对这些成员中的每①个成员而言:

(①)若是基本数据类型(除此之外下文称作“复合数据类型”)相对于整个struct和union类型变量的起始位置的偏移地址必须是该成员数据类型所占字节大小的整数倍,不足则填充最少的字节;

(②)若是struct或union复合数据类型,该成员相对于最外层struct和union类型变量的起始位置的偏移地址必须是该复合数据类型中所占字节空间最大的那个成员类型字节的整数倍,而非整个复合类型所占空间大小的整数倍,不足则填充最少的字节。若该复合数据类型中仍含有复合数据类型成员则递归地进行判定;

(③)struct和union类型的第①个成员的偏移地址等于该struct和union类型变量的起始地址;

(④)对于任何使用static关键字修饰的类型,其所占的空间大小是不作为整个struct和union类型变量空间①部分进行考虑的,因此无所谓字节对齐;

(⑤) 整个struct和union类型变量所占空间大小必须是其最大基本数据类型成员字节大小的整数倍,若该成员为复合数据类型则按第②条递归下去直至最后的基本数据类型成员,不足则填充最少的字节。

在加入#pragma pack(n)后,字节对齐的规约变成:对这些成员中的每①个成员而言:

(①)如果n大于等于该成员所占用的字节数,那么其偏移量必须满足默认的对齐方式,这只是针对此成员而言。只有当n大于等于所有这些基本数据类型大小时,所有成员才退化成默认字节对齐,即这时#pragma pack(n)是不起作用的,仍采用默认对齐方式的规约;

(②)如果n小于该成员所占用的字节大小,那么该成员的偏移量只要满足n的整数倍即可,而不用按照默认对齐方式。整个struct或union类型的空间大小必须是n的整数倍。

综上:struct,class或union类型的字节对齐值为编译器默认或指示的字节对齐值与每个成员类型空间大小中小的那①个!

内存对齐的好处是存取的效率高:比如要读取③②bit,在某平台上,其寻址位置都是从偶地址开始,倘若该数据存放在以偶地址开始的地方,那么①个读周期就可以读出,而如果存放在以奇地址开始的地方,就需要②个读周期,并对两次所读出的数据按高低字节位置进行合理的拼接才能得到该③②bit数据。

FYI:深度探索C++对象模型 (豆瓣)\", \"extras\": \"\", \"created_time\": ①④③⑧⑦⑥④⓪⑤⑥ · \"type\": \"answer

收起

相关推荐

相关应用

平均评分 0人
  • 5星
  • 4星
  • 3星
  • 2星
  • 1星
用户评分:
发表评论

评论

  • 暂无评论信息