0%

41. 了解隐式接口和编译器多态

面向对象编程世界总是以显示接口运行期多态解决问题。

Templates 中,隐式接口和编译器多态更加重要。

隐式接口,不基于函数签名式,而是由有效表达式组成。

阅读全文 »

状态之间的转移:

进程五种状态的变迁

如果有大量处于阻塞状态的进程,进程可能会占用着物理内存空间,显然不是我们所希望的,毕竟物理内存空间是有限的,被阻塞状态的进程占用着物理内存就一种浪费物理内存的行为。

所以,在虚拟内存管理的操作系统中,通常会把阻塞状态的进程的物理内存空间换出到硬盘,等需要再次运行的时候,再从硬盘换入到物理内存。

阅读全文 »

为什么要有虚拟内存?

  • 第一,虚拟内存可以使得进程对运行内存超过物理内存大小,因为程序运行符合局部性原理,CPU 访问内存会有很明显的重复访问的倾向性,对于那些没有被经常使用到的内存,我们可以把它换出到物理内存之外,比如硬盘上的 swap 区域。
  • 第二,由于每个进程都有自己的页表,所以每个进程的虚拟内存空间就是相互独立的。进程也没有办法访问其他进程的页表,所以这些页表是私有的,这就解决了多进程之间地址冲突的问题。
  • 第三,页表里的页表项中除了物理地址之外,还有一些标记属性的比特,比如控制一个页的读写权限,标记该页是否存在等。在内存访问方面,操作系统提供了更好的安全性。

这就是虚拟内存的作用,为了引入虚拟内存,操作系统做了很多工作。

阅读全文 »

通过第一个进程的创建来解释 xv6 是如何开始运行的,让我们得以一窥 xv6 提供的各个抽象是如何实现和交互的。

进程

进程是一个抽象概念,它让一个程序可以假设它独占一台机器。进程向程序提供“看上去”私有的,其他进程无法读写的内存系统(或地址空间),以及一颗“看上去”仅执行该程序的CPU。

xv6 使用页表(pagetable,由硬件实现)来为每个进程提供其独有的地址空间。页表将虚拟地址(x86 指令所使用的地址)翻译(或说“映射”)为物理地址(处理器芯片向主存发送的地址)。

阅读全文 »

操作系统接口

操作系统的工作:

  • 将计算机的资源在多个程序间共享,并且给程序提供一系列比硬件本身更有用的服务。
  • 管理并抽象底层硬件
  • 多路复用硬件,使得多个程序可以(至少看起来是)同时运行的
  • 最后,给程序间提供一种受控的交互方式,使得程序之间可以共享数据、共同工作

操作系统通过接口向用户程序提供服务。让接口的设计依赖于少量的机制mechanism),而通过这些机制的组合提供强大、通用的功能。提供机制而不是方法。

阅读全文 »

26 尽可能延后变量定义式的出现时间

27 尽量少做转型动作(Minimize casting)

28 避免返回 handles 指向对象内部成分

29 为 异常安全(exception-safe)努力是值得的

30 透彻了解 inlining 的里里外外

31 将文件间的编译依存关系降至最低


尽量延后变量定义式的出现,这样做可增加程序的清晰度并改善程序效率。


const_cast,将对象的常量性转除(cast away the constness)。

dynamic_cast

reinterpret_cast

static_cast,强迫隐式转换,将 non-cast 转为 cast,或则 int 转为 double。

18 让接口容易被正确使用,不易被误用

如果用户企图使用某个借口却没有获得他预期的行为,这个代码不该通过编译;如果代码通过了编译,它的作为就该是客户所想要的。


19 设计 class 犹如设计 type

20 宁以 pass-by-reference-to-const 替换 pass-by-value

21 必须返回对象时,别妄想返回其 reference

22 将成员变量声明为 private

23 宁以 non-membernon-friennd 替换 member 函数

24 若所有参数皆需类型转换,请为此采用 non-member 函数

25 考虑写出一个不抛出异常的 swap 函数

了解 C++ 默默编写并调用哪些函数

  • copy 构造函数
  • copy assignment 操作符
  • 析构函数
  • default 构造函数

这些函数都是 public 且 inline 的。

阅读全文 »