[读书笔记] 深入探索C++对象模型-第三章 Data语义学(上)

原创 2016年08月28日 17:01:53

注:以下部分图片来自原书

1. 关于类的大小,有三个因素会影响类的大小:

a. 语言本身所造成的额外负担,例如虚基类,相应的子类会存在某种形式的指针,或者直接指向虚基类子对象,或者指向一个存放着虚基类子对象地址或者偏移量的表格。又如,虚函数,继承自含有虚函数基类的子类会含有一个指向虚函数表的指针。总之这些都会增加类对象的大小。

b. 对齐操作,即为了使总线的传输效率达到最高,类大小会被进行对齐操作,调整为某一个数字大小的倍数,32位机器上,通常为4的倍数,也就是说,一个类的实际占用大小为3,那么会被调整为4,类似的东东。

例如以下例子:


c. 编译器对于特殊情况的优化处理,例如对于大小为1的虚基类,某些编译器会提供特殊的支持,在此种情况下,空的虚基类会被视为子类对象最开头的一部分,这样就不会占用任何额外的空间,在此模型下类Y和Z的大小如下:


注意虚拟继承中不管虚基类在继承体系中出现了多少次,它在子类中始终只有一份,这也是虚继承由来的原因之一,所以对于类A的大小,首先是虚基类X大小为1,加上Y的大小减去因虚基类X而配置的大小(因为虚基类在子类中只有一份,所以要减掉在Y中的大小),结果是4,同理Z的大小也是4,目前类A的大小是9,对齐后是12(VS2015中测试是8,估计是因为堆空虚基类进行优化了)。

2. 关于数据成员的存取。

a. 对于静态数据成员,使用指针操作和对象操作效率是一样的,例如:a.staticMember = 0和pA->staticMember = 0都会被转化成为:A::staticMember = 0,所以二者是一样的。另外,对一个静态成员取地址会得到相应类型的指针,而不是指向类成员的指针(关于类成员指针的概念后续会有详细记录)。

b. 对于非静态成员,通过类对象操作数据成员时,编译器会把类对象的起始地址加上类成员的偏移,例如:a._y=0.0,那么地址&a._y等于&a + (&A::_y - 1),(指向类成员的指针偏移量总是被加上1,这个之后会有详细记录),如果在子类中操作继承而来的虚基类(非虚基类的不会有间接性)的数据成员,需要进行一层间接性,这个之后会有详细的整理。

3. 对于操作a.x = 0.0和pA->x = 0.0在以下情况下效率是不一样的:当x来源于虚基类时,在编译期,我们无法pA的确切类型(只可能知道静态类型,而不知道动态类型),他可能指向某个基类,也可能指向某个子类,因此无法知道x确切的偏移位置,所以存取操作必须要延迟到执行期,经由一个额外的简介引导来解决。如果使用a,则不会存在这样的不确定性,因为a的类型是确定知道的,所以成员的偏移在编译期就是确定的。

注:关于指针的静态类型和动态类型,例如:

B b; //B public inheriance of A
A* pA = b;
此时pA的静态类型为A,动态类型为B,也就是说,静态类型时固定不可变的,而动态类型可变,实际上C++的多太机制就是通过父类指针指向不同的子类对象,变换其动态类型实现的。

后续会继续整理本章的其他内容。








版权声明:本文为博主原创文章,未经博主允许不得转载。

《深度探索C++对象模型》读书笔记——关于对象【for_wind】

//整理之,分享之,欢迎指正。for_wind 1、C与C++的区别:       概括来说,C程序中程序性地使用全局数据[注1]。而C++采用ADT(abstract data tpye)或...
  • for_wind
  • for_wind
  • 2014年03月28日 14:08
  • 1382

《深度探索C++对象模型(Inside The C++ Object Model )》学习笔记

来源:http://dsqiu.iteye.com/blog/1669614 之前一直对C++内部的原理的完全空白,然后找到《Inside The C++ Object Model》...
  • freeking101
  • freeking101
  • 2017年03月03日 14:52
  • 1659

深度探索C++对象模型:6.执行期语意学

第6章:执行期语意学 想象一下我们有下面这个简单的式子: if(yy ==xx.getValue( ))... 其中xx和yy定义为: X xx; Y yy; Class Y定义为: C...
  • walkerkalr
  • walkerkalr
  • 2014年01月11日 20:23
  • 1017

[读书笔记] 深入探索C++对象模型-第三章 Data语义学(下)

整理第三章最后的部分内容,关于数据成员指针的,之前竟然没听过类数据成员指针一说,果然路漫漫其修远兮啊。 注:以下例子和图片来源于原书。 1. 数据成员指针是指指向类数据成员的指针,其内容为对应数据成员...
  • beyongwang
  • beyongwang
  • 2016年09月05日 22:27
  • 217

[读书笔记] 深入探索C++对象模型-第三章 Data语义学(中)

继续整理第三章的内容(以下部分图片来自于原书): 1. 在只有继承没有多态的情况下,子类是的内容就是父类加上子类特有的数据成员,例如,对于如下两个类,Point2d和Point3d,后者公有继承自前者...
  • beyongwang
  • beyongwang
  • 2016年09月04日 23:18
  • 308

[读书笔记] 深入探索C++对象模型-第五章-构造、析构、拷贝语义学(上)

继续整理第五章的内容,关于累的三个重要函数:构造函数,析构函数,拷贝构造函数。注:以下部分图片来自原书 1. 无继承情况下的对象构造。 当类中存在虚函数时,编译器会对该类产生膨胀作用, 例如如下类: ...
  • beyongwang
  • beyongwang
  • 2016年09月20日 00:17
  • 333

[读书笔记] 深入探索C++对象模型-第二章《构造函数语义学》(下)

继续整理第二章节剩下的内容。 1. 对于明确d
  • beyongwang
  • beyongwang
  • 2016年08月25日 00:05
  • 247

[读书笔记] 深入探索C++对象模型-第五章-构造、析构、拷贝语义学(中)

继续整理第五章的内容,关于对象复制的。  对于默认的拷贝赋值操作符,在如下情况下不会表现出按位拷贝(bitwise copy:关于按位拷贝,实际就是不使用拷贝构造函数或者拷贝赋值操作符,这里的不使用是...
  • beyongwang
  • beyongwang
  • 2016年09月22日 23:43
  • 332

[读书笔记] 深入探索C++对象模型-第四章-Function语义学(上)

开始整理第四章的内容,关于函数的东西。 1. 静态成员函数不可以是const的,原因是因为this指针,详细参考:http://blog.csdn.net/beyongwang/article/det...
  • beyongwang
  • beyongwang
  • 2016年09月10日 21:43
  • 262

[读书笔记] 深入探索C++对象模型-第二章《构造函数语义学》(中)

继续整理第二章的内容,是关于拷贝构造函数的。 1. 有三种情况会以一个对象的内容作为另一个类对象的初始值: a. 明确的以一个对象初始化另一个对象,例如: A a1 = a2;//会调用类A的拷贝构造...
  • beyongwang
  • beyongwang
  • 2016年08月23日 20:28
  • 157
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[读书笔记] 深入探索C++对象模型-第三章 Data语义学(上)
举报原因:
原因补充:

(最多只允许输入30个字)