《Thinking in C++, 2nd Edition》笔记-第一章(Introduction to Objects)

1 关于类和对象

Alan Kay总结的SmallTalk(第一个成功的OO语言,C++发展的基础之一)的五个特性:
1.一切事物都是对象。可以把对象想象成一个变量,它存储数据,又可以向它提出请求,使它自己执行操作。理论上,可以把任何需要解决的问题的概念成分看成一个对象。
2.一个程序是一组通过发送消息告知彼此去做什么的对象组成。
3.每个对象都有自己的内存,可以由其它的对象组成。
4.每个对象都有一个类型,对象是一个类型的实例。
5.一个类的所有对象可以接收相同的消息。
 

对一个对象的请求(操作)被定义为 接口。一个 是用来描述拥有相同属性和行为的集合。类也是一个数据类型,就像float数(有相同的属性和行为),不同的是,编程者用类来匹配问题,而用已存在的数据类型来描述在机器上的存储单元。
例子:
Light lt;
lt.on();
Light是类,lt是对象,可以进行的请求是开灯,关灯,变亮,变暗。

2 为什么要隐藏实现

为什么类应该只暴露给用户必要的接口,而隐藏那些不必要的?
1,类的创建者改变隐藏的部分时不会影响到客户;
2,不隐藏意味着客户也可以随意使用,增大导致BUG的风险;
3,防止类库过于庞大(对外提供的接口过多)。

因此有了 访问控制,public, protected, private。
 

3 复用实现的方式:聚合和组合

对类而言,最简单的复用就是直接用类的对象,也可以在另一个类里用这个类的对象(组合或聚合,composition(aggregation),通常说的 has-a关系)。
如果不用菱形,意味着不用关注是组合还是聚合。
聚合:表示两个对象之间是整体和部分的弱关系,部分的生命周期可以超越整体。空心菱形。
组合:表示两个对象之间是整体和部分的强关系,部分的生命周期不能超越整体。实心菱形。

组合简单灵活,而继承因为在编译时的需要对继承的类进行编译时限制,所以没那么灵活。因此类之间的关系应该优先使用组合。防止过度复杂的设计。
 

 

4 复用接口的方式:继承


一个类不仅描述着一组对象的特性,也和其它类有关联。两个类可以有相同的属性和行为,但是其中一个可能有更多的发生或者能处理更多的消息(或者处理方式不同)。继承可以用来描述这种关系:基类和派生类。
如上所述,与基类区别派生类的两种方法:添加新的函数或者overriding基类的函数(在子类中重写基类中已经存在的函数)。
一个派生类可以用来替换基类( is-a关系),但一个基类不能用来替换派生类(访问不了派生类添加的新函数),这个可以称为 like-a关系。

5 可互换的多态对象

处理继承的类对象时,经常希望不用考虑它的类型,直接作为基类来处理,这样写代码时不用判别类型,在派生新的类时也不用修改用基类来处理的函数,大大的改进设计和减小维护成本。问题的关键在于将派生类当作基类处理时,编程者不希望在编译时确定函数调用哪段代码,而是在运行时,根据派生类的类型,调用派生类本身的函数。

非OOP编译器在函数调用时是 早绑定(early binding):编译器对指定的函数名进行调用,链接器确定调用将执行的代码的绝对地址。
OOP采用 晚绑定(late binding):在给对象发送消息时,程序运行之前不去确定要执行的代码。编译器保证这个函数存在,并完成参数及返回值类型检查,但是不知道准确的执行代码,编译器在真正调用的地方插入一段特殊的二进制代码,这段代码通过对象自身中的信息在运行时计算被调用函数的地址。这样,指针的内容不同,对象产生不同的行为。

关键字virtual表明编程者需要这个函数拥有迟绑定特性。

把派生类指针当作基类指针的过程称作 向上转型(upcasting)

6 创建和销毁对象

C++认为效率是最重要的因素,所以它给编程者提供了选择,通过把对象放在 静态存储区上可以来决定最大化运行时速度、存储和生命周期。
栈是程序执行期间微处理器可以直接使用的内存,栈上的变量通常被称作automatic或scoped变量。静态存储区就是程序开始运行前分配的一小块固定内存区域。就创建和销毁对象的速度优先来说,选用栈或静态存储区,但是牺牲了灵活性,因为你必须在写程序时知道确切的数量,生存期(编译器决定),对象类型。如果这用来解决一般性问题,会是很大的限制。这种情况下可以用另一种方式,在内存池上动态创建,即 。这种方法直到运行时才需要知道有多少个对象,生存期,具体类型。用new创建,用delete销毁。这种创建方式会消耗长得多的时间(在栈上只需要一个指令向下移动一个栈指针,一个指令往回移动)。

7 异常处理:处理错误

一个 异常是从错误发生出抛出的一个对象,这个对象能够被设计用来处理这种异常的异常处理器捕获。异常处理就好像是错误发生时程序进入另一条路径执行,也因此不会干扰正常的执行代码,这样就不用不断的做错误检查,从而使编码更简单。与函数返回的错误代码不同,异常不能被忽略,必须保证在某个地方被处理,最后,异常要使程序恢复正常。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Bruce Eckel 《Thinking in Java》(Java编程思想)作者。Eckel有20年专业编程经验,并自1986年起教育人们如何撰写面向对象程序,足迹遍及全球,成为一位知名的 C++教师和顾问,如今兼涉Java。他是C++标准委员会拥有表决权的成员之一,曾经写过另五本面向对象编程书籍,发表过150篇以上的文章,是多本计算机杂志的专栏作家。Eckel开创Software Development Conference的C++、Java、Python等多项研讨活动。拥有应用物理学学士和计算机工程学硕士学位。 目录 译者序 前言 第1章 对象导言 第2章 对象的创建与使用 第3章 C++中的C 第4章 数据抽象 第5章 隐藏实现 第6章 初始化与清除 第7章 函数重载与默认参数 第8章 常量 第9章 内联函数 第10章 名字控制 第11章 引用和拷贝构造函数 第12章 运算符重载 第13章 动态对象创建 第14章 继承和组合 第15章 多态性和虚函数 第16章 模板介绍 附录A 编码风格 附录B 编程准则 附录C 推荐读物 索引 第2卷:实用编程技术 出版者的话 专家指导委员会 译者序 前言 第一部分 建立稳定的系统 第1章 异常处理 第2章 防御性编程 第二部分 标准C++库 第3章 深入理解字符串 第4章 输入输出流 第5章 深入理解模板 第6章 通用算法 第7章 通用容器 第三部分 专题 第8章 运行时类型识别 第9章 多重继承 第10章 设计模式 第11章 并发 附录 附录A 推荐读物 附录B 其他 索引 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值