深入探索C++对象模型笔记之六 —— Data语意学

来源:互联网 发布:json.encode 编辑:程序博客网 时间:2024/05/22 00:30

对类或类的实例进行sizeof取大小

 

大小主要有三个因素影响:

1.语言本身所造成的额外负担:语言支持虚函数和虚拟基类时,导致一些额外负担。

2.编译器对于特殊情况所提供的优化处理:某些编译器会对empty virtual base class提供特殊支持。

3.边界对齐

 

Data Member的绑定

 

全局变量作用域与类的作用域。

 

早期C++的两种防御性程序设计风格:

 

1.把所有的data members放在class声明起头处,以确保正确地绑定

 

2.把所有的inline functions,不管大小都放在class声明之外

 

Data Member的布局

 

Nonstatic data members 在 class object 中的排列顺序将和其被声明的顺序一样,任何static data members都不会放进对象布局中。

 

C++ Standard允许编译器把那些内部产生的members自由放在任何位置上,甚至放在那些被程序员声明出来的members之间。

 

C++ Standard也允许编译器将多个access sections (public,private,protected)之中的data members自由排列,不必在乎它们出现在class 声明中的次序。(当前各家编译器都是把一个以上的access section连锁在一起,依照声明的次序,成为一个连锁区块)

 

Data Member的存取

提出问题:

Point3d origin,*pt = &origin;

 

origin.x = 0.0;

pt->x = 0.0;

 

问:通过origin存取和通过pt存取,有什么重大区别?

 

Static Data Members的存取:被视为一个global变量(作用域在class里)。每一个member的存取许可(public等)以及与class的关联,并不会导致任何空间上或执行时间上的额外负担(不论是在个别的class objects或是在static data member本身)。

 

对Static Data Members来说,通过一个指针和通过一个对象来存取member,结论完全相同,它只有唯一一个实体,而且存取路径是那么直接。

 

如果多个类中存在相同名字的static data members,编译器使用name-mangling进行命名处理,避免名字冲突。

 

Nonstatic Data Members的存取:直接存放在每一个class object之中,除非经由明确的(explicit)或暗喻(implicit)classobject,没有办法直接存取它们。

 

只要程序员在一个member function中直接处理一个nonstatic data member,所谓的“implicit class object”就会发生。(其实就是使用了this指针)

 

这里通过一个指针和通过一个对象来存储member就有很大的区别:“当Point3d是一个derived class,而在其继承结构中有一个virtual base class,并且存储的member是一个从该virtual base class 继承而来的member时,就会有重大差异”。

 

这时候我们不能说pt必然指向哪一种class type,所以这个存取操作必须要延迟至执行期,经由一个额外的间接导引,才能够解决。

但如果使用origin,就不会有这些问题,其类型无疑是Point3d class,而即使它继承自virtual base class,members 的offset位置也在编译时期就固定了。

 

 

 

 

原创粉丝点击