深度探索C++ 对象模型(阅读笔记)(原创)
Inside The C++ Object Model
--关于对象
由 王宇 原创并发布 :
让我肃然起敬并崇拜的牛人:
Bjarne Stroustrup - C++之父 (www.stroustrup.com)
Stanley B. Lippman - 本书作者、C++代言人、C++编译器的设计者之一
侯捷 - 本书译者 (jjhou.boolan.com)
第一章 关于对象
C++在布局及存取时间上主要的额外负担是由virtual引起的。
两个概念:
1) virtual function机制: 用以一种有效的“执行期绑定”(runtime binding)
2) virtual base class: 用以实现“多次出现在继承体系中的 base class, 有一个单一而被共享的实体”
1.1 C++对象模型(The C++ Object Model)
类数据成员(class data memeber): 静态(static)和非静态的(nonstatic)
类成员函数(class member function):静态(static)函数、非静态函数(nonstatic)和虚(virtual)函数
在C++对象模型中,Nonstatic data memeber 被配置与每一个class object之内,static data members则被存放在所有的class object之外,static和nonstatic function members也被放在所有的class object之外,virtual functions则以两个步骤支持之:
1、每个class产生出一堆指向virtual function的指针,放在表格之中。这个表格被成为virtual table(vtbl).
2、每个class object被添加了一个指针,指向相关的vitrual table.通常这个指针被称为vptr. vptr的设置和重置都由每一个class的constructor、destructor和copy assignment运算符自动完成。每一个class所关联的type_info object(用于支持runtime type identification,RTTI)也经由vitual talbe被指出来,通常是放在表格的第一个slot处。
优点:它的空间和存取时间的效率
缺点:如果应用程序代码本身未曾改变,但所用到的class object的nonstatic data memeber有所改变,那么那些应用程序代码同样得重新编译。
对象模型如何影响程序:
class X 定义了一个copy constructor, 一个virtual destructor,和一个virtual function foo:
X foobar() { X xx; X *px = new X; //foo() 是一个virtual function xx.foo(); px->foo(); delete px; return xxx; }
这个函数可能在内部转换为:
void foobar(X &_result) { ... //扩展xx.foo()但不使用virtual机制 //以 _result 取代xx foo(&_result); //使用virtual机制扩展px->foo() ( *px->vtbl[ 2 ] )( px ); ... }
结论是:
以下方式不能使用virtual机制:
X xx;
xx.foo()
以下方式可以使用virtual机制:
X *px = new X;
px->foo();
1.2 关键词所带来的差异
关键词的困扰:
在C++观念上,struct 是可以替代class的,但仍然声明public、protected、private等等存取区段。
策略性正确的struct:
C程序员的巧计有时候却成为C++程序员的陷阱。例如把单一元素的数组放在一个struct的尾端,于是每个struct objects可以拥有可变大小的数组:
struct mumberl{
/* stuff */
char pc [1];
};
如果改用class来声明,在C++中凡处于同一个access section的数据,必定保证以其声明次序出现在内存布局当中,然而被放置在多个access section中的各笔数据,排列次序就不一定了,所以最好的忠告就是:不要那么做。
1.3 对象的差异:
C++ 程序设计模型直接支持三种程序设计典范(programming paradigms)
1)程序模型(procedural model),就像C一样
2)抽象数据类型模型(abstract data type model,ADT),该模型所谓的“抽象”是和一组表达式(public接
口)一起提供,而其运算定义任然隐而未明。
3)面向对象模型
需要多少内存才能够表现一个class:
1)其nonstatic data members的总和大小
2)加上任何由于alignment的需求而填补上去的空间。(alignment就是将数值调整到某数的倍数。在32位计算机上,通常alignment为4bype,以使bus的“运输量”达到最高效率)(我在此处理解为对齐内存中的对象。)
3)加上为了支持virtual而由内部产生的任何额外负担
指针的类型:
寻址出来的object类型不同。也就是说,“指针类型”会教导编译器如何解释某个特定地址中的内存内容及其大小
例:
int *p 地址:1000 - 1003
string *pstr 地址:1000 - 1015
viod *pV 地址:指向1000,而地址空间我们不知道!这就是为什么一个类型为void*的指针只能够含有一个地址,而不能通过它操作所指之object的缘故。必须进行转型。
转型(cast)其实是一种编译器指令。大部分情况下它并不改变一个指针所含的真正地址,它只影响"被指出之内存的大小和其内容"的解释方式
加上多态之后的布局:
class Bear : public ZooAnimal{ public: Bear(); ~Bear(); void rotate(); virtual void dance(); protected: enum Dances{ .. }; Dances dances_known; int cell_block; };
Bear b("Yogi");
Bear *pb = &b;
Bear &rb = *pb;
假设一:
Bear b;
ZooAnimal *pz = &b;
Bear *pb = &b;
差别是pb所涵盖的地址包含整个Bear object,而pz所涵盖的地址只包含Bear object中的ZooAnimal suboject
除了virtual机制,pz不能指向Bear 中的函数
pz的类型将在编译时期决定一下两点:
(1)固定的可用接口,也就是说pz只能够调用ZooAnimal的public接口
(2)该接口的access level
假设二:
Bear b;
ZooAnimal za = b;//这会引起切割(sliced)
za.rotate(); //调用ZooAnimal::rotate();
为什么za的vptr不指向Bear的virtual table?
za并不是(而且也绝不会是)一个Bear,它是(并且只能是)一个ZooAnimal。多态所造成的“一个以上的类型”的潜在力量,并不能够实际发挥在"直接存取 object"这件事情上。有一个似是而非的观念:OO程序设计并不支持对object的直接处理
ZooAnimal za;
ZooAniall *pza;
Bear b;
Panda *pp = new Panda;
pza = &b;
一个pointer或一个reference之所以支持多态,是因为它们并不引发内存中任何“与类型有关的内存委托操作(type-dependent commitment)”;会受到改变的只是他们所指向的内存的“大小和内容解释方式(参考上面的‘指针的类型’)”而已
相关推荐
通过阅读《深度探索C++对象模型》的学习笔记,我们可以更深入地理解C++的底层机制,这对于成为一名精通C++的开发者来说是必不可少的。同时,结合《Effective C++》的学习,可以让我们写出更加高效、健壮的C++代码。...
本篇文章基于《深度探索C++对象模型笔记》的部分内容,对C++对象模型进行深入探讨。 #### 对象模型的基本概念 在C语言中,数据与处理数据的操作通常是分开的,通过一系列分布于不同函数中的算法来处理共享的外部...
《深度探索 C++对象模型》是一本深入剖析C++内部机制的著作,它揭示了C++如何在内存中表示和管理对象,以及由此产生的性能影响。通过对C++对象模型的了解,程序员可以编写出更高效、更少错误的代码。 在C++中,类是...
在深入探讨C++对象模型这一主题时,我们首先需要理解C++语言的核心概念,它是一种静态类型、编译式、通用的、大小写敏感、不支持自动垃圾回收的编程语言。C++以其强大的面向对象特性著称,这些特性包括封装、继承和...
深度探索C++对象模型(6)这是这个系列笔记的第7篇了,我们还在和构造函数打交道,以前写程序时怎么根本没有考虑过构造函数的事情呢?原来编译器为我们做了这么多的事情,我们都不知道.,要想完全搞明白,看来还需要一段...
本压缩包包含的是一系列关于C++的深度学习资料,包括阅读笔记,涵盖了多个核心主题,如C++的对象模型、STL的高效使用、C++中的陷阱和缺陷,以及虚函数和虚继承等关键概念。下面将对这些知识点进行详细阐述。 首先,...
《C++与Linux系统编程深度探索》 C++是一种强大且通用的编程语言,它以其高效、灵活性和面向对象的特性被广泛应用于软件开发、游戏引擎、系统编程等多个领域。而Linux作为开源的操作系统,拥有丰富的开发环境和工具...
在编程语言方面,笔记可能涉及Java、Python、C++或JavaScript等,包括它们的基本语法、面向对象编程、异常处理、数据结构和算法等核心主题。对于初学者,这些笔记将提供清晰的学习路径;对于经验丰富的开发者,它们...
深度学习是人工智能领域的一个重要分支,它通过模拟人脑神经网络的工作原理,让计算机..."deeplearningbook-chinese"文件名表明这可能是一本中文版的深度学习教材或笔记,涵盖上述知识点,适合初学者逐步掌握深度学习。
Qt Quick的使用,QML的语法学习,Quick基础,控件和对话框的运用,图形动画的基础知识,图形效果的创建,粒子系统的构建,canvas的使用,模型和视图的概念,多媒体应用的开发,以及如何将QML与C++深度集成,使用...
这些算法通过提取人脸的关键特征并建立模型来进行识别。在实际应用中,我们需要创建一个ROS节点,捕获来自摄像头的图像,然后利用OpenCV进行预处理(如灰度化、直方图均衡化)、特征提取和匹配,最后将识别结果发布...
例如,Python的面向对象编程、Java的异常处理、C++的模板机制,或是JavaScript的异步编程模型。理解并掌握这些语言的特性有助于提高代码质量和效率。 2. 操作系统:操作系统是计算机的心脏,学习笔记中可能涵盖了...
**BMP位图格式自学笔记** BMP(Bitmap)是一种常见的位图图像文件格式,广泛应用于Windows操作系统中。它以未经压缩的原始像素数据存储图像,使得BMP文件通常较大,但同时也保证了图片质量。BMP格式适用于学习图像...
【标题】: "前置学习笔记" 涵盖了在深入探索信息技术领域之前需要掌握的基础知识,这是一份全面的学习指南,旨在为初学者或有经验的IT从业者提供一个稳固的起点。这份笔记包含了计算机科学的基本概念、编程语言的...
6. **Objective-C++/Jupyter Notebook**: Objective-C++是Objective-C和C++的结合,允许在Objective-C代码中使用C++特性。Jupyter Notebook则是一种交互式的计算环境,支持多种编程语言,如Python、R、Julia等,便于...
3. **样例代码**:对于数据结构和算法的学习,压缩包可能包含各种算法的实现,如排序算法(冒泡排序、快速排序)、搜索算法(二分查找、深度优先搜索)等,通过阅读和修改这些代码,学生能加深对算法的理解。...