《深度探索C++对象模型》读书笔记[第一章]

1 关于对象

加上封装后的布局成本

封装特性不会带来任何空间或执行器的不良回应,C++在布局以及存取时间上主要的额外负担是由 virtual 引起的,包括:
1. virtual function 机制 用以支持一个有效率的"执行期绑定"(runtime binding)
2. virtual base class 用以实现"多次出现在继承体系中的 base class, 有一个单一而被共享的实体".
此外还有一些多重继承下的额外负担,发生在"一个 derived class 和其第二或后继之 base class 的转换"之间。
### 1.1 C++ 对象模式
Nonstatic data members 被配置于每一个 class object 之内, static data members 则被存放在所有的 class object 之外. Static 和 nonstatic function members 也被放在所有的 class object 之外。 Virtual functions 则以两个步骤支持之:
1. 每一个 class 产生出一堆指向 virtual functions 的指针,放在表格之中.这个表格被称为 virtual table(vtbl).
2. 每一个 class object 被添加了一个指针, 指向相关的 virtual table。通常这个指针被称为vptr. vptr 的设定(setting)和重置(resetting)都由每一个 class 的 consructor、destructor 和 copy assignment 运算符自动完成. 每一个class所关联的 type_info object(用以支持 runtime type identification, RTTI)也经由 virtual table 被指出来,通常是放在表格的第一个 slot 处.

1.2 关键词所带来的差异

c++中凡处于同一个 access section 的数据,必定保证以其声明次序出现在内存布局当中。然而被放置在多个access sections 中的各笔数据,排列次序就不一定了。

1.2.1 关键词的困扰

class 与 struct 的差异:
C++中的 struct 和 class 基本是通用的,唯有几个细节不同:
使用 class 时,类中的成员默认都是 private 属性的;而使用 struct 时,结构体中的成员默认都是 public 属性的。
class 继承默认是 private 继承,而 struct 继承默认是 public 继承(《C++继承与派生》一章会讲解继承)。
class 可以使用模板,而 struct 不能(《模板、字符串和异常》一章会讲解模板)。

1.3 对象的差异

c++ 以下列方法支持多态:

  1. 经由一组隐含的转化操作。例如把一个 derived class 指针转化为一个指向其 public base type 的指针。
  2. 经由 virtual function机制。
  3. 经由dynamic_cast 和 typeid运算符。
    多态的主要用途是经由一个共同的接口来影响类型的封装,这个接口通常被定义在一个抽象的base class 中。
    需要多少内存才能够表现一个class object?一般而言要有:
  4. 其 nonstatic data members的总和大小。
  5. 加上任何犹豫 alignmennt的需求而填补(padding)上去的空间(可能存在于members之间,也可能存在于集合体边界)。
  6. 加上为了支持 virtual 而由内部产生的任何额外负担(overhead)。

1.3.1 指针的类型

“指向不同类型之各指针”间的差异,既不在其指针表示法不同,也不在其内容(代表一个地址)不同,而是在其所寻址出来的object类型不同。也就是说,“指针类型”会教导编译器如何解释某个特定地址中的内存内容及其大小。
转型(cast)其实是一种编译器指令。大部分情况下它并不改变一个指针所含的真正地址,它只影响“被指出内存的大小和其内容”的解释方式。

1.3.2 加上多态之后

多态是一种威力强大的设计机制,允许你继承一个抽象的public接口之后,封装相关类型。c++通过class的pointers和references来支持多态,这种程序设计风格就称为“面向对象”。

posted @ 2022-02-17 12:14  liyakai  阅读(48)  评论(0编辑  收藏  举报