![]()
内容推荐 本书基于Qt框架介绍C++面向对象程序设计机制。全书共9章:第1章介绍面向对象程序设计所需的预备知识;第2~8章的内容包括类和对象、继承与派生、类的静态成员与常成员、多态、友元与运算符重载等面向对象的知识,并同步穿插介绍了信号与槽、界面、Qt容器、事件系统与绘图、I/O设备、主窗口和多文档应用程序编程等Qt框架的知识;第9章以实际项目为背景,提供了3个完整的综合实例。本书注重知识点与实践的紧密结合,强调读者编程习惯的养成和自主能力的培养,内容编写上贯彻“实例式”学习法,提供的实例兼顾示范性、实用性、有趣性和拓展性。本书还提供了习题、实验和附录,以全方位支撑读者的实际学习需求。 本书可作为高等院校计算机相关专业“面向对象程序设计”课程的教材,也可作为各类软件开发人员的参考书。 目录 第1章 程序设计基础 1.1 C++程序设计语言 1.1.1 程序设计语言的发展历史 1.1.2 C和C++ 1.2 不同于C语言的C++常见语法 1.2.1 输入和输出操作 1.2.2 bool类型 1.2.3 函数的默认值与函数的声明 1.2.4 引用 1.2.5 动态存储分配 1.2.6 初始化 1.2.7 结构体 1.2.8 强制类型转换 1.2.9 基于范围的for循环 1.3 纯C++项目的开发流程 1.3.1 项目的创建过程 1.3.2 项目内容 1.3.3 项目的构建与运行 1.3.4 编译方式 1.4 程序设计方法 1.4.1 面向过程的结构化程序设计 1.4.2 面向对象程序设计 1.5 Windows图形用户界面编程 1.5.1 基于事件驱动的消息机制 1.5.2 一个最简单的Windows GUI程序 1.5.3 一个完整的Windows GUI程序 1.6 基于Qt的图形用户界面编程 1.6.1 一个最简单的Qt GUI程序 1.6.2 Qt程序的发布 1.6.3 设置程序图标 1.7 编程实例——模拟病毒程序 课后习题 实验1C++和GUI编程初探 第2章 类和对象 2.1 初识类和对象 2.1.1 类的定义 2.1.2 对象的定义与使用 2.1.3 this指针 2.1.4 项目文件的组织 2.2 构造函数和析构函数 2.2.1 构造函数 2.2.2 析构函数 2.3 Qt窗口及部件初探 2.3.1 窗口类 2.3.2 部件类 2.4 更复杂的类和对象 2.4.1 类的组合 2.4.2 对象数组 2.4.3 类的嵌套 2.5 相关指针 2.5.1 对象指针 2.5.2 对象数据成员指针 2.5.3 类数据成员指针 2.5.4 普通函数指针 2.5.5 成员函数指针 2.6 Qt信号与槽通信机制 2.6.1 信号与槽 2.6.2 关联信号与槽 2.7 编程实例——学生成绩的排名 课后习题 实验2类的使用以及简单GUI交互 第3章 继承与派生 3.1 类的继承与派生 3.1.1 派生类的定义 3.1.2 继承方式 3.1.3 重定义成员函数 3.1.4 赋值兼容规则 3.2 派生类的构造与析构函数 3.2.1 实现方式 3.2.2 调用顺序 3.3 二义性问题与虚基类 3.3.1 二义性问题 3.3.2 虚基类 3.4 Qt自定义派生类 3.4.1 使用向导创建项目 3.4.2 静态创建类对象和动态创建类对象的区别 3.4.3 对象树机制 3.4.4 自定义信号和槽 3.5 Qt中的界面 3.5.1 命名空间 3.5.2 快速实现界面设计 3.5.3 信号与槽的自动关联 3.6 Qt常用部件 3.6.1 按钮部件 3.6.2 输入部件 3.6.3 显示部件 3.7 编程实例——计算器 课后习题 实验3派生类、信号与槽和界面设计 第4章 类的静态成员与常成员 4.1 静态成员 4.1.1 静态数据成员 4.1.2 静态成员函数 4.2 Qt标准对话框 4.2.1 QDialog类的层次 4.2.2 颜色对话框及其静态成员函数 4.2.3 文件对话框及其静态成员函数 4.2.4 字体对话框及其静态成员函数 4.3 常成员 4.3.1 常数据成员 4.3.2 常成员函数 4.4 Qt中常见的数据类 4.4.1 QChar类 4.4.2 QString类 4.4.3 QByteArray类 4.5 程序国际化 4.6 编程实例——常用信息的获取与展示 课后习题 实验4静态成员和常成员的使用 第5章 多态 5.1 静态多态——模板 5.1.1 函数模板 5.1.2 类模板 5.2 Qt中的容器 5.2.1 列表 5.2.2 向量 5.2.3 链表 5.3 动态多态 5.3.1 虚函数 5.3.2 调用方式 5.3.3 实现原理 5.4 抽象类与纯虚函数 5.4.1 抽象类 5.4.2 纯虚函数的定义 5.5 编程实例——猴子选大王 课后习题 实验5多态的实现与容器的使用 第6章 Qt事件及绘图 6.1 事件处理机制 6.2 常见事件 6.2.1 鼠标事件 6.2.2 滚轮事件 6.2.3 键盘事件 6.2.4 定时器事件 6.3 Qt二维绘图 6.3.1 绘图系统 6.3.2 画笔和画刷 6.3.3 图像绘图设备 6.4 Qt抽象部件的可视化实现 6.4.1 QWidget类层次 6.4.2 抽象部件的派生类实现 6.5 使用OpenCV库进行图像处理 6.5.1 图像的读写 6.5.2 灰度化与二值化 6.5.3 图像的平滑 6.5.4 视频的读写 6.5.5 OpenCV和Qt的结合 6.6 编程实例——爱心表白小程序 课后习题 实验6事件处理与绘图 第7章 数据I/O 7.1 标准C++中的流 7.1.1 流类库 7.1.2 文件类型 7.1.3 使用流实现文件I/O 7.2 Qt的I/O设备 7.2.1 I/O设备类层次 7.2.2 访问I/O设备的过程 7.3 Qt文件操作 7.3.1 QFile类 7.3.2 QTemporaryFile类 7.3.3 QSaveFile类 7.3.4 QFileInfo类 7.4 Qt目录操作 7.4.1 序言 内容介绍 本书以图形界面编程框 架Qt为载体讲授C++面向对 象机制,使读者能从面向过 程编程迅速过渡到图形界面 的面向对象编程,进而熟练 地掌握C++面向对象编程的 基本知识和技能,为使用 C++语言工具开发图形用户 交互界面、解决实际问题奠 定坚实的程序设计基础和正 确的编程思想。面向的读者 本书适合已具备一定的面向 过程程序设计的基础(掌握 了数据类型、语句、分支、 循环、函数、数组、指针等 基础编程概念),希望进一 步学习C++面向对象程序设 计和图形界面程序设计的读 者。本书可作为高等院校计 算机相关专业“面向对象程 序设计”课程的入门教材, 建议先修课程为“C语言程序 设计”。因为Java是在C++ 语言的基础上衍生出来的, 若读者具有Java知识背景, 则对本书所讲的一些面向对 象机制不会陌生。但由于书 中还涉及一些关于指针的操 作,建议读者在开始阅读之 前先对指针等相关概念进行 了解。 如何使用本书我们 的目标是编写一本既能讲清 楚C++面向对象机制,又能 让学生立刻上手进行图形界 面程序编程的书籍,既适合 作为教材由教师讲授,又能 指导学生独立阅读和编程。 为了实现这个目标,本书采 用了以下方式。1. 以Qt框 架为载体,讲授C++面向对 象机制读者在学习编程语言 时普遍地希望能够尽快看到 编程成果,以获得体验感; 也希望运行效果能尽量和常 见软件运行效果一致,以获 得真实感和实用感。但多数 传统讲授C++面向对象机制 的书籍只是讲授与面向对象 相关的概念和知识,对于读 者而言,虽然学了很久,程 序仍运行在一个黑黑的、与 大众普遍所接受的图形界面 不一样的命令行界面,学习 的成就感和兴趣就会大打折 扣。同时,基础的面向过程 程序设计的学习(如C语言 )也是使用命令行界面,对 于同样的场景、熟悉的运行 界面,读者很难直观和快速 地感受到面向对象机制的强 大之处。一旦失去了兴趣, 学习就很难进行下去。 本 书基于Qt框架,从第1章就 开始引入图形界面,并在前 几章中迅速引入Qt Designer等界面设计工具和 信号与槽等交互功能的实现 机制,使读者能很快地写出 简单的图形界面交互应用, 然后在后续的章节中再持续 引入面向对象机制中的概念 ,并结合这些概念介绍更多 Qt类库的使用和Qt特有的机 制,从而使读者能在Qt框架 中循序渐进地掌握C++面向 对象机制,并从简单到复杂 ,写出更加完善、功能更加 丰富的应用。2. 贯彻“实例 式”学习法,在实例中理解 、掌握和深化概念本书贯彻 “实例式”学习法,每个知识 点或通过实例引入,或通过 实例加以说明和分析,读者 可在实例中理解、掌握和深 化概念。每章包含一个比较 综合的编程实例,帮助读者 对本章所学进行了解和掌握 。这些实例生动有趣,且大 多涉及C++之外的一些知识 内容,希望读者能在觉得有 趣、实用的同时尽量扩充知 识面。本书的第9章给出了3 个完整的应用程序,目的是 提供更多的实例资源,示范 运行效果,引导读者针对实 际应用需求进行分析和设计 ,最终完成开发工作。 3. 注重编程习惯的培养 ,注重与动手实践的衔接在 实现功能的基础上,编程人 员还应养成良好的编程习惯 。本书注重对编程习惯的培 养。例如,书中从标识符的 命名规范、文件的组织、类 成员权限的设计理念、模块 高内聚低耦合的追求等多个 方面进行了引导,希望通过 本书的学习,读者不只是能 写出程序,而是能写出高质 量的程序。注重与动手实践 的衔接,例如强调语言规范 版本和编译器实现细节的不 同之处,提示如何利用编程 环境的自动补全等功能帮助 开发,如何快速查看和获取 帮助,介绍开发调试细节, 帮助读者在学与做之间搭建 一座理论与实践的桥梁。4. 注意与前序、后继课程之间 的衔接本书对前序课程(基 础编程知识,如一个学期的 “C语言程序设计”课程)与 本课程相衔接的知识点进行 了梳理,并进行了总结,以 填补知识体系的漏洞,帮助 读者尽快适应本课程的学习 。本书注意本课程和后继课 程的联系,将一些概念融入 本课程的知识点讲解和实例 中。例如,在类相关指针、 容器等章节中融入“数据结 构”课程中的栈、队列、链 表等概念;在Qt事件处理及 绘图章节延伸出“数字图像 处理”课程中的图像处理算 法等;各章最后的编程实例 分别涉及了“计算机病毒”“ 计算机网络”“算法分析与设 计”等课程的一些知识,希 望给读者留下一个浅显的印 象,以便在后续课程中继续 深入学习。5. 具备知识的 拓展性本书的重点在于介绍 面向对象机制,限于篇幅的 关系,不能对Qt界面框架中 的每个模块、每个类及其功 能函数都详细地进行介绍, 但书中对常用的操作进行了 简单的描述,以期读者在未 来面对更复杂的应用开发时 ,能在这些文字的指引下做 更深入的学习与掌握。课程 进度安排本书适合一个学期 、3个学分的教学设计。建 议教学安排如下。 序号教学形式课时数教 学 内 容 1授课2第1章程序设计基 础(1.1节~1.4节)2授课2 第1章程 精彩页 第3章继承与派生 继承与派生是面向对象程序设计的第二大特征,它允许在已有类(称为基类或父类)的基础上,根据自己的需要向类中添加更多的属性和方法,从而创建出一个新的类(称为派生类或子类)。继承与派生实际是从不同的角度来看的同一个过程: 保持已有类的特性而构成新类的过程称为类的继承; 在已有类的基础上新增自己的特性而产生新类的过程称为类的派生。派生类除了具有新增的属性和方法外,还自动具有基类的所有属性和方法。对于派生类,还可以继续派生出新类,因此基类和派生类是相对而言的。类层层派生,可形成复杂的继承结构。 继承机制的引入使程序设计时可以层层抽取出对象之间的共同点,从而减少了代码的冗余; 避免了不必要的重复编程,增加了代码的可重用性。派生出的新类可以基于已有工作进一步扩展,以快速开发出高质量的程序。 视频讲解 3.1类的继承与派生 3.1.1派生类的定义 派生类只有一个直接基类的继承,称为单继承,否则称为多继承。在图31中,汽车和船都是单继承,它们都只有一个基类——交通工具; 而房车有两个基类——房子和汽车; 水陆两栖车也有两个基类——汽车和船,它们都是多继承。 图31类的继承关系 派生类的定义格式如下。 class 派生类名:继承方式 基类1,…,继承方式 基类n {//基类可以有多个,之间用逗号隔开,每个基类都要写明继承方式 派生类新增成员的声明 }; 基类需要是已有的类,派生类是新定义的类,派生类的基类在派生类名后以“:”开头的基类列表中指明。当单继承时,此处只有一个基类; 当多继承时,有多个基类,之间通过逗号隔开。每个基类都需要指明继承方式,且每个继承方式都只限制对紧随其后的基类的继承。继承有public、private、protected 3种方式。 (1) public: 表示公有继承。 (2) private: 表示私有继承。 (3) protected: 表示保护继承。 下面举例说明。为了定义派生类,首先要有交通工具类Conveyance作为基类,其定义和实现如下。 class Conveyance//交通工具类 { double speed; //时速 public: double getSpeed() { return speed; } }; 然后在该类的基础上派生出汽车类Car,其定义和实现如下。 class Car: public Conveyance//汽车类 { int wheelsNum; //车轮数 public: int getWheelsNum() { return wheelsNum; } }; { a.showInfo(); } 在已有Car类型对象myCar的情况下: Conveyance x1,&x2=myCar,*ptr; ptr=&myCar; x1=myCar; func(myCar); 上述语句都是合法的。引用x2只代表了myCar对象中属于Conveyance类的那部分属性的内存空间; 指针ptr虽然实际指向派生类对象myCar,但由于它自己是Conveyance类型的指针,所以只能调用getSpeed()函数,而无法通过它去操作getWheelsNum()函数; 只从myCar中复制了speed属性的值给x1对象,wheelsNum的值被舍弃; func()函数内部执行的是Conveyance类的showInfo()函数。 在以后的编程中,读者经常会看到把派生类对象当作基类对象使用的情形。 3.2派生类的构造与析构函数 之前说到派生类会继承基类中的全部成员,其实有一些例外,就是构造函数和析构函数。它们都不能被派生类所继承,在派生类中需要声明和实现自己的构造函数,以及在必要的时候自定义析构函数。 视频讲解 3.2.1实现方式 派生类构造函数在实现时只需对本类中新增的成员进行初始化,基类部分的初始化会自动调用基类构造函数完成。这里有以下几点建议。 (1) 当基类中声明了带有形参的构造函数时,派生类也应声明带形参的构造函数,并传参数给基类构造函数。 (2) 当基类中声明了不带参的构造函数时,派生类构造函数可以不向基类构造函数传递参数,此时基类部分的初始化调用的是基类不带参构造函数。 (3) 若基类中未声明构造函数,在派生类中也可以不声明,此时都采用系统默认生成的构造函数。例如,3.1节中各个派生类对象生成时均是调用了派生类和基类的默认构造函数。 构造函数的实现格式如下。 派生类类名::派生类类名(基类所需形参,本类数据成员所需形参):基类名(基类实参) { 新增数据成员赋初值; //更建议写在初始化列表处 } 形参列表中形参的顺序无规定,前后可以调换。“基类实参”通常由派生类构造函数形参列表中的“基类所需形参”给出,但也可以是常量、全局变量等。对基类构造函数传递参数必须在派生类的初始化列表中进行。 例如,首先在Conveyance类定义的public部分添加构造函数如下。 Conveyance(int spd):speed(spd) { cout<<"Constructor of Conveyance."<} 然后为Car类在类内添加公有构造函数 |