从 C 到 C++¶
先从 C 语言的组织方式出发,了解面向对象程序设计要解决的问题。
C程序的组织方式¶
C语言如何管理和使用自定义数据类型?
- 用结构体把相关数据放在一起。
- 用函数处理这些结构体数据。
- 调用者负责按照约定调用函数并维护合法状态。
- 当数据和规则越来越多时,约定容易散落在不同文件中。
C示例:struct Clock¶
声明自定义数据类型¶
时钟的状态可以用结构体表达,一个结构体就是一种自定义数据类型。
基于结构体的自定义数据类型
- 状态集中 :
hour、minute、second放在同一个结构体中 - 字段公开 :C 结构体字段默认可以被外部直接访问
- 规则不在结构体里 :合法性检查需要依赖外部函数或调用者自觉
用函数操作结构体¶
函数负责修改 Clock,由函数逻辑保证数据的约束规则,但数据本身仍然是公开的。
用函数操作结构体
函数无法完全限制对结构体的访问规则
- 规则在函数中 :只要调用
setTime(),时间范围就能被检查。 - 问题还没消失 :调用者仍然可以绕过
setTime直接写字段。
数据可以被任意修改¶
对公开数据的直接赋值可能破坏对象的合法状态。
绕过函数直接修改数据
数据可能被置于错误状态
- 非法状态 :
minute不应该是 99,second不应该是负数。 - 责任落在调用者身上 :每个调用者都必须记住字段的含义和范围。
- 维护风险 :项目越大,越难保证所有地方都遵守规则。
C带来的问题¶
程序变大后,对数据的访问规则会散落在各处,而大型程序需要更强的组织边界。我们希望把字段和规则绑定得更紧。
- 字段含义写在注释里,调用者可能没看到。
- 合法性检查写在某些函数里,但不是所有修改路径都会调用它。
- 多人协作时,不同文件可能用不同方式修改同一类数据。
- 修复错误时,需要追踪所有直接访问字段的位置。
C++的方法:面向对象程序设计¶
Object-Oriented Programming,OOP
让对象自己管理状态和规则¶
对象不仅是数据的容器,它也负责维护数据的使用规则。

如果 minute 被直接改成 99,谁应该负责阻止这件事?
- 限制直接修改字段 :用户不能够随意修改
hour、minute、second这些字段。 - 必须通过接口访问 :用户必须通过
setTime()接口函数来修改字段的状态。 - 规则定义在接口中 :
setTime()接口函数中应声明合法性检查规则
把同类对象封装为类¶
类描述一类对象的共同结构和行为,是程序中的代码模块;对象保存自己的具体状态,是程序中的运行实例。

OOP的基本特征¶
抽象¶
Abstraction
抽象不是把所有细节都搬进程序,而是为当前问题保留必要特征,其核心是 “简化” 和 “建模”。
- 从复杂的现实世界中,提炼出与当前问题域相关的核心本质,并忽略无关的细节,保留对解决问题有意义的状态和行为。
- 降低复杂性,让程序员能够关注于“做什么”,而不是“如何做”。
- 在面向对象程序中,通常用类(class)和接口(interface)表达抽象设计,一个设计良好的类,其名称和公开方法就清晰地表达了它的抽象意图。
封装¶
Encapsulation
封装是实现抽象的手段,让程序模块拥有边界和约束,也让错误更容易被定位。
- 用内部保存的数据表示对象状态,例如
Clock的hour、minute、second,对外隐藏对象的内部实现细节。 - 用对外提供的操作表示对象行为,例如
setTime()和show(),外部调用必须通过公开接口进行访问。 - 用行为逻辑约束对象必须遵循的规则,例如
minute必须在 0 到 59 之间,保护对象状态的完整性,防止外部代码随意修改而导致程序出错。
继承¶
Inheritance
继承是构建类之间 “is-a” 关系的方式,可以减少面向对象程序中的重复代码,提高代码重用性。
- 允许一个类(子类/派生类)继承另一个类(父类/基类)的属性和方法。
- 实现代码复用,并建立层级化的类型结构。
多态¶
Polymorphism
多态是面向对象设计的精髓,意味着 “一个接口,多种方法”。
- 允许你用父类的指针或引用来调用子类中重写(override)的方法。
- 让程序具有更好的扩展性,可以基于统一的接口处理不同类型的对象。
面向对象程序设计方法¶
程序由封装数据与行为的类模块组成,通过对象间的协作交互执行程序功能。
- 先识别系统里有哪些对象
- 再判断每个对象应该保存什么状态
- 继续判断每个对象应该提供什么行为
- 最后让对象通过公开接口协作完成任务
OOP关注对象的责任与协作¶
过程式程序重在步骤,对象式程序重在责任。
C:调用者负责遵守规则
责任分散:每个调用点都可能成为错误入口。
C++:类型自己维护规则
责任集中:对象把规则封装在自己的接口里。
一个完整的C++示例¶
C++:抽象、封装、继承、多态