Data 语意学---Data member的存取效率

《深度探索C++对象模型》

对于data member来说,有两种情况

static data member数据

每一个static data member只有一个实体,存放在程序的data segment之中,无论以何种方式,无论类的继承关系如何复杂,存取路径都是非常直接

Nonstatic data members

直接存放在一个class object之中,是属于一个对象的,是需要一个叫做偏移量的值来索引的。

尤其是虚拟继承,虚拟继承将为“经由base class subobject存取class members”导入一层新的间接性,譬如:

Point3d *pt3d,origin;

pt3d->_x = 0.0

其转型效率在_x是一个struct member、一个class member、单一继承、多重继承的情况下都完全相同。但如果_x是一个virtual base class的member,存取速度会比较慢一点。如果使用下面的这种方式存取

origin.x = 0.0

pt->x = 0.0;

“从origin存取和从pt存取有什么重大的差异”? 答案是:当point3d是一个derived class,而在其继承结构中有一个virtual base class,并且被存取的Member(如本例的x)是一个从该virtual base  class继承而来的member时,就会有重大的差异。这时候我们不能够说pt必然指向哪一种class type(因此我们也就不知道编译时期这个member真正的offset位置),所以这个存取操作必须延迟至执行期,经由一个额外的间接引导,才能够解决,但如果使用origin就不会有这些问题,其类型无疑是pointed3d
class,而即使它继承自virtual base class,members的offset位置也在编译期间就固定了,一个积极进取的编译器甚至可以静态地经由origin就解决掉对x的存取。

总结:从上面的分析可以发现,多态是C++三大特性之一,也是很重要的一部分内容,是为了更好的编程而存在的内容,但是在有些地方就是成了累赘,比如在这里,印象中记得C++运行比较慢,也许就是在这时候拖累了C++的速度。

时间: 2024-10-12 16:07:45

Data 语意学---Data member的存取效率的相关文章

Data Member 的存取

考察以下代码: Point3d origin; origin.x = 0.0; 此例中 x 的存取成本是什么? 答案则是视 x 和 Pointd 而定(别打脸, 我知道这是废话). 具体的呢? 因为 x 可能是个 static member, 也可能是个 nonstiatic member; Point3d 可能是个独立的 class, 也可能是另一个 单一的class 派生而来:甚至可能是从多重继承或虚拟继承而来(请不要小看其他人的代码中的可能性, 你都很有可能不知道 C++ 还能这么写, 有

Data 语意学 —— 数据成员的绑定、布局与存取

数据成员的绑定 早期的 C++ 编译器为了能够正确绑定具体的数据成员,规定了以下两种行为: 所有的 data member 必须放在 class 声明的起始处: 所有的 inline functions 放在 class 声明之外: 从早期的编译器可以知道,绑定数据成员类型必须要在 class 声明完成之后才能确定,但是现在 C++ 编译器不必要要求上面的规定,也可以正确绑定具体的数据成员,例如: extern float x; class Pointer{ public: Pointer(fl

C++对象模型——Data Member的存取(第三章)

3.3    Data Member的存取 已知下面这段代码: Point3d origin; origin.x = 0.0; x的存取成本是什么? 答案视x和Point3d如何声明而定,x可能是个 static member,也可能是个nonstatic member.Point3d可能是个独立(非派生)的 class,也可能从另一个单一的base class 派生而来;虽然可能性,但它甚至可能是从多重继承或虚拟继承而来.下面数节将依次检验每一种可能性. 先看这样一个问题,如果有两个定义,or

data语意学

引例: class X{}; class Y:public virtual X{}; class Z:public virtual X{}; class A:public Y,public Z{}; X Y Z A类对象的大小是多少?? 1> 没有提供empty virtual base特殊支持的编译器:1 8 8 12 2> 提供了empty virtual base特殊支持的编译器:1 4 4 8 一个class的data members,一般而言,可以表现这个class在程序执行时的某种

《深度探索c++对象模型》chapter3 Data语意学

一个空的class:如 class X{} ; sizeof(X)==1; sizeof为什么为1,他有一个隐晦的1 byte,那是被编译器安插进去的一个char,这使得class2的两个objects得以在内存中配置独一无二的地址: X a,b; if(&a==&b) cerr<<"yipes!"<<endl; class X{}; class Y:public virtual X{}; class Z:public virtual X{};

Data语意学里的一些问题

今天和小伙伴讨论了第三章data语意学的指一些的知识,感觉很有必要总结一下,似乎不总结知识就会溜走,所以冒夜写一下吧. 首先看这样的一个继承的例子: class X{ }; class Y: public virtualX { }; class Z: public virtualX { }; class A: public Y,publicZ { }; 分别对X Y Z A取sizeof,结果可能是1, 8, 8, 12.当然我的机器是1, 4, 4, 8.一般来说老的机器会是第一种结果,因为编

深度探索C++对象模型 第三章 Data 语意学

一个有趣的问题:下列 类 sizeof大小 class X{}    //1 class Y:public virtual X{} //4 or 8 class Z:public virtual X{} // 4 or 8 class A:public Y,public Z{} // 8 or 12 主要原因:为了保持每一个类生成对象在内存中的唯一性,编译器必须要给空类生成一个char来维持object的唯一性: 而virtual继承中,仅保持了base class的指针,有些编译器会继承bas

【C++】深度探索C++对象模型读书笔记--Data语意学(The Semantics of data)

1. 一个空类的大小是1 byte.这是为了让这一类的两个对象得以在内存中配置独一无二的地址. 2. Nonstatic data member 放置的是“个别的class object”感兴趣的数据,static data members则放置的是“整个class”感兴趣的数据. 3. C++对象模型把nonstatic data members直接放在每一个classs object之中.对于继承而来的nonstatic data members(不管是virtual 还是nonvirtua

第三章、Data语意学

无虚继承的空类占一个字节,用于标记该类.有虚继承的空类至少占4个字节(可能继承的空类占很大空间).对齐情况class X{float i;//8char j;//1int k;//4double b;//下面重新的字节8,上面用来对齐};sizeof(X)=24 class Y{char j;//1int k;//4};sizeof(Y)=8 class Z{char j;//1int k;//4double b;};sizeof(Y)=16 1.Data Member的绑定有两种情况:情况一: