第十五章 面向对象程序设计

OOP:概述

  • 面向对象程序设计(object-oriented programming)的核心思想是数据抽象、继承和动态绑定。
  • 继承(inheritance):
    • 通过继承联系在一起的类构成一种层次关系。
    • 通常在层次关系的根部有一个基类(base class)。
    • 其他类直接或者简介从基类继承而来,这些继承得到的类成为派生类(derived class)。
    • 基类负责定义在层次关系中所有类共同拥有的成员,而每个派生类定义各自特有的成员。
    • 对于某些函数,基类希望它的派生类个自定义适合自己的版本,此时基类就将这些函数声明成虚函数(virtual function)。
    • 派生类必须通过使用类派生列表(class derivation list)明确指出它是从哪个基类继承而来。形式:一个冒号,后面紧跟以逗号分隔的基类列表,每个基类前都可以有访问说明符。class Bulk_quote : public Quote{};
    • 派生类必须在其内部对所有重新定义的虚函数进行声明。可以在函数之前加上virtual关键字,也可以不加。C++11新标准允许派生类显式地注明它将使用哪个成员函数改写基类的虚函数,即在函数的形参列表之后加一个override关键字。
  • 动态绑定(dynamic binding,又称运行时绑定):
    • 使用同一段代码可以分别处理基类和派生类的对象。
    • 函数的运行版本由实参决定,即在运行时选择函数的版本。

定义基类和派生类

定义基类

  • 基类通常都应该定义一个虚析构函数,即使该函数不执行任何实际操作也是如此。
  • 基类通过在其成员函数的声明语句前加上关键字virtual使得该函数执行动态绑定
  • 如果成员函数没有被声明为虚函数,则解析过程发生在编译时而非运行时。
  • 访问控制:
    • protected : 基类和和其派生类还有友元可以访问。
    • private : 只有基类本身和友元可以访问。

定义派生类

  • 派生类必须通过类派生列表(class derivation list)明确指出它是从哪个基类继承而来。形式:冒号,后面紧跟以逗号分隔的基类列表,每个基类前面可以有一下三种访问说明符的一个:publicprotectedprivate
  • C++11新标准允许派生类显式地注明它将使用哪个成员函数改写基类的虚函数,即在函数的形参列表之后加一个override关键字。
  • 派生类构造函数:派生类必须使用基类的构造函数去初始化它的基类部分。
  • 静态成员:如果基类定义了一个基类成员,则在整个继承体系中只存在该成员的唯一定义。
  • 派生类的声明:声明中不包含它的派生列表。
  • C++11新标准提供了一种防止继承的方法,在类名后面跟一个关键字final

类型转换与继承

  • 理解基类和派生类之间的类型抓换是理解C++语言面向对象编程的关键所在。
  • 可以将基类的指针或引用绑定到派生类对象上。
  • 不存在从基类向派生类的隐式类型转换。
  • 派生类向基类的自动类型转换只对指针或引用类型有效,对象之间不存在类型转换。

虚函数

  • 使用虚函数可以执行动态绑定。
  • OOP的核心思想是多态性(polymorphism)。
  • 当且仅当对通过指针或引用调用虚函数时,才会在运行时解析该调用,也只有在这种情况下对象的动态类型才有可能与静态类型不同。
  • 派生类必须在其内部对所有重新定义的虚函数进行声明。可以在函数之前加上virtual关键字,也可以不加。
  • C++11新标准允许派生类显式地注明它将使用哪个成员函数改写基类的虚函数,即在函数的形参列表之后加一个override关键字。
  • 如果我们想覆盖某个虚函数,但不小心把形参列表弄错了,这个时候就不会覆盖基类中的虚函数。加上override可以明确程序员的意图,让编译器帮忙确认参数列表是否出错。
  • 如果虚函数使用默认实参,则基类和派生类中定义的默认实参最好一致。
  • 通常,只有成员函数(或友元)中的代码才需要使用作用域运算符::)来回避虚函数的机制。

抽象基类

  • 纯虚函数(pure virtual):清晰地告诉用户当前的函数是没有实际意义的。纯虚函数无需定义,只用在函数体的位置前书写=0就可以将一个虚函数说明为纯虚函数。
  • 含有纯虚函数的类是抽象基类(abstract base class)。不能创建抽象基类的对象。

访问控制与继承

  • 受保护的成员:

    • protected说明符可以看做是publicprivate中的产物。
    • 类似于私有成员,受保护的成员对类的用户来说是不可访问的。
    • 类似于公有成员,受保护的成员对于派生类的成员和友元来说是可访问的。
    • 派生类的成员或友元只能通过派生类对象来访问基类的受保护成员。派生类对于一个基类对象中的受保护成员没有任何访问特权。
  • 派生访问说明符:
    • 对于派生类的成员(及友元)能否访问其直接积累的成员没什么影响。
    • 派生访问说明符的目的是:控制派生类用户对于基类成员的访问权限。比如struct Priv_Drev: private Base{}意味着在派生类Priv_Drev中,从Base继承而来的部分都是private的。
  • 友元关系不能继承。
  • 改变个别成员的可访问性:使用using
  • 默认情况下,使用class关键字定义的派生类是私有继承的;使用struct关键字定义的派生类是公有继承的。

继承中的类作用域

  • 每个类定义自己的作用域,在这个作用域内我们定义类的成员。当存在继承关系时,派生类的作用域嵌套在其基类的作用域之内。
  • 派生类的成员将隐藏同名的基类成员。
  • 除了覆盖继承而来的虚函数之外,派生类最好不要重用其他定义在基类中的名字。

构造函数与拷贝控制

虚析构函数

  • 基类通常应该定义一个虚析构函数,这样我们就能动态分配继承体系中的对象了。
  • 如果基类的析构函数不是虚函数,则delete一个指向派生类对象的基类指针将产生未定义的行为。
  • 虚析构函数将阻止合成移动操作。

合成拷贝控制与继承

  • 基类或派生类的合成拷贝控制成员的行为和其他合成的构造函数、赋值运算符或析构函数类似:他们对类本身的成员依次进行初始化、赋值或销毁的操作。

派生类的拷贝控制成员

  • 当派生类定义了拷贝或移动操作时,该操作负责拷贝或移动包括基类部分成员在内的整个对象。
  • 派生类析构函数:派生类析构函数先执行,然后执行基类的析构函数。

继承的构造函数

  • C++11新标准中,派生类可以重用其直接基类定义的构造函数。
  • using Disc_quote::Disc_quote;,注明了要继承Disc_quote的构造函数。

容器与继承

  • 当我们使用容器存放继承体系中的对象时,通常必须采用间接存储的方式。
  • 派生类对象直接赋值给积累对象,其中的派生类部分会被切掉。
  • 在容器中放置(智能)指针而非对象。
  • 对于C++面向对象的编程来说,一个悖论是我们无法直接使用对象进行面向对象编程。相反,我们必须使用指针和引用。因为指针会增加程序的复杂性,所以经常定义一些辅助的类来处理这些复杂的情况。

文本查询程序再探

  • 使系统支持:单词查询、逻辑非查询、逻辑或查询、逻辑与查询。

面向对象的解决方案

  • 将几种不同的查询建模成相互独立的类,这些类共享一个公共基类:

    • WordQuery
    • NotQuery
    • OrQuery
    • AndQuery
  • 这些类包含两个操作:
    • eval:接受一个TextQuery对象并返回一个QueryResult
    • rep:返回基础查询的string表示形式。
  • 继承和组合:
    • 当我们令一个类公有地继承另一个类时,派生类应当反映与基类的“是一种(Is A)”的关系。
    • 类型之间另一种常见的关系是“有一个(Has A)”的关系。
  • 对于面向对象编程的新手来说,想要理解一个程序,最困难的部分旺旺是理解程序的设计思路。一旦掌握了设计思路,接下来的实现也就水到渠成了。

Query程序设计:

操作 解释
Query程序接口类和操作  
TextQuery 该类读入给定的文件并构建一个查找图。包含一个query操作,它接受一个string实参,返回一个QueryResult对象;该QueryResult对象表示string出现的行。
QueryResult 该类保存一个query操作的结果。
Query 是一个接口类,指向Query_base派生类的对象。
Query q(s) Query对象q绑定到一个存放着string s的新WordQuery对象上。
q1 & q2 返回一个Query对象,该Query绑定到一个存放q1q2的新AndQuery对象上。
`q1 q2`
~q 返回一个Query对象,该Query绑定到一个存放q的新NotQuery对象上。
Query程序实现类  
Query_base 查询类的抽象基类
WordQuery Query_base的派生类,用于查找一个给定的单词
NotQuery Query_base的派生类,用于查找一个给定的单词
BinaryQuery Query_base的派生类,查询结果是Query运算对象没有出现的行的集合
OrQuery Query_base的派生类,返回它的两个运算对象分别出现的行的并集
AndQuery Query_base的派生类,返回它的两个运算对象分别出现的行的交集

第十五章 面向对象程序设计相关推荐

  1. c++primer(第五版) 第十五章 面向对象程序设计习题答案

    纯原创    转载请注明出处:http://blog.csdn.net/axuan_k 略过书上有现成代码的题目 15.1  15.2 15.1 虚成员是基类中的概念 基类中的某些函数希望它的派生类能 ...

  2. 第二十五章 面向对象------封装、内置函数、反射、动态导入

    1.封装 什么是封装? 1.对外部隐藏内部的属性,以及实现细节,给外部提供使用的接口 注意:封装有隐藏的意思,但不是单纯的隐藏 学习封装的目的:就是为了能够限制外界对内部数据的访问 python中属性 ...

  3. java语言程序设计基础篇课后答案_《Java语言程序设计:基础篇》课后复习题答案-第十五章.pdf...

    <Java语言程序设计:基础篇>课后复习题答案-第十五章 Chapter15Graphics 1. Theycoordinateshouldincreaseandthexcoordinat ...

  4. 《Erlang程序设计》第十五章 ETS和DETS:大数据的存储机制

    第十五章 ETS和DETS:大数据的存储机制 Table of Contents 第十五章 ETS和DETS:大数据的存储机制 15.1 表的基本操作 创建和打开表 插入表 查找元组 释放表 15.2 ...

  5. C++程序设计原理与实践 习题答案 第十五章 第15章习题答案

    第十五章:容器和迭代器 习题答案 Document 本章的文本编辑器实现,添加了一些功能 Document.h Document.cpp main.cpp 测试 List_Circular.h 我自己 ...

  6. 20190901 On Java8 第十五章 异常

    第十五章 异常 要想创建健壮的系统,它的每一个构件都必须是健壮的. 异常概念 C++的异常处理机制基于 Ada,Java 中的异常处理则建立在 C++的基础之上(尽管看上去更像 Object Pasc ...

  7. 【正点原子STM32连载】第四十五章 SD卡实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  8. 异步fifo_正点原子开拓者FPGA开发板资料连载第十五章 IP核之FIFO实验

    1)实验平台:正点原子开拓者FPGA 开发板 2)摘自<开拓者FPGA开发指南>关注官方微信号公众号,获取更多资料:正点原子 3)全套实验源码+手册+视频下载地址:http://www.o ...

  9. 机器学习入门-西瓜书总结笔记第十五章

    西瓜书第十五章-规则学习 一.基本概念 二.序贯覆盖 三.剪枝优化 四.一阶规则学习 五.归纳逻辑程序设计 1.最小一般泛化 2.逆归结 一.基本概念 机器学习中的 "规则"(ru ...

最新文章

  1. 使用Spring Rest和Spring Data JPA和H2以及Spring Boot示例的Restful API
  2. Mysql学习总结(12)——21分钟Mysql入门教程
  3. 闲鱼:1月13日至1月19日冻结涉欺诈用户1.1万个
  4. NAT集群部署solo之session server
  5. python 正则匹配电话与ip
  6. QML 自定义鼠标光标
  7. Powermill数控编程培训,潇洒模具三步教您精通cnc数控编程
  8. JTA transaction unexpectedly rolled back (maybe due to a timeout)
  9. 大三小学期入门课程第六课:规划
  10. android 挂载多个u盘,实现多U盘挂载
  11. ro模式数据库mysql_ro数据库-和ro数据库相关的内容-阿里云开发者社区
  12. java 获取天气_获取免费天气(Java抓取百度天气)
  13. RuPengWang项目
  14. 解决php报错Warning: date(): It is not safe to rely on the system's timezone settings
  15. 程序员写春联,秒杀全场!网友:不愧是聪明绝顶的“程序猿”!
  16. VSM仪器工作原理及产品概述
  17. python邮箱爆破_企业邮箱爆破脚本
  18. windows的navicat 连接 linux的mysql服务器问题汇总
  19. 苹果ipad教程] iTunes如何备份数据及操作文件(仅限于备份非资料库信息,第三方软件不限)
  20. BPM工作流 前端表单JS 处理细节

热门文章

  1. DeFi衍生品协议dFuture未来5日将通过公测奖励100万枚DFT
  2. SAP License:CKMLCP运行物料帐时单个物料冲突无法运行
  3. 风控人需知:信贷风险流程中的决策矩阵与实操
  4. 信贷常用风控报表(二)
  5. vue中组件的data为什么是一个函数
  6. 【Objective-C】探索Category底层的实质
  7. Samba服务器安装测试
  8. Hello log4net——做一个实用好用的log4net的demo(转)
  9. python协程--yield和yield from
  10. Dropbox Interview – Design Hit Counter