版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C++程序设计精要教程第1章复习指导.pptx第2章复习指导.pptx第3章复习指导.pptx第4章复习指导.pptx第5章复习指导.pptx第6章复习指导.pptx第7章复习指导.pptx第8章复习指导.pptx第9章复习指导.pptx第10章复习指导.pptx第11章复习指导.pptx第12章复习指导.pptx第13章复习指导.pptx第14章复习指导.pptx第15章复习指导.pptx华中科技大学学习指导与习题解答第1章C++引论本章重点计算机的体系结构,可变特性不同的内存RAM、ROM、EPROM的用途、内存编址。操作系统的引导,引用程序的分段加载,操作系统与应用程序的互动。二进制、八进制、十进制、十六进制的相互转换,常见的二进制运算。汇编语言的寄存器、指令、过程及其与C和C++函数调用、重载的关系。C++的发展历史与C++的特点。C和C++的语法图与程序流程图。如何安装VisualStudio2019、编译模式及如何编写、编译和调试程序。第1章C++引论学习指导体系结构:理解运算器、控制器、存储器、输入设备、输出设备等基本概念及其用途。内存:按字节编址。内存按可变特性分为RAM、ROM、EPROM,可对应存储什么样的变量。操作系统引导:从ROM中固定位置开始执行引导程序,检查内存、设备、装入操作系统程序。应用程序加载:操作系统加载后在内存中分为数据段、代码段、栈段、堆段。操作系统与应用程序互动:操作系统传给应用程序main函数命令行参数,应用程序依靠操作系统完成内存分配、输入输出、网络通信等功能,结束时告知操作系统是否正常结束。进制:二进制逢2进1、每位两个状态。十六进制逢16进1、每位十个状态:0,1,…,a,b,…,f。进制转换:重点掌握二进制和十进制的转换。二进制运算:加、减、乘、除、移位、逻辑运算与位逻辑运算。汇编语言:理解不同寄存器的用途,理解指令的构成、掌握常用指令、掌握数据定义与过程定义。编译程序:可将C和C++的函数编译为汇编语言的过程,调用函数时的实参传递通过压栈完成,返回值通常在EAX和EDX寄存器中第1章C++引论学习指导函数重载:C++的同名函数在编译为汇编语言的过程时,在过程名中通常包含函数参数的类型信息,以此区分同名的重载函数。C++的发展历史:BCPL语言→B语言→C语言→CwithClasses→C++。Java、C#、Python等都是基于C++设计的。C++的最新国际标准为C++2020。C++的特点:(1)兼容C,(2)强类型,(3)面向对象的异常处理,(4)运算符重载,(5)多继承,(6)编译为机器指令,(7)混合型面向对象,(8)模板、类型推导、Lambda、概念、约束等增强特点。语法图:使用标准图形符号描述程序设计语言的语法结构。擅长描述语法概念中的递归定义模式。程序流程图:使用标准图形符号描述程序的执行步骤和流向。VisualStudio2019:集成开发环境,包含编辑、编译、调试、发布等功能。调试时可设断点并施加条件,按Ctrl+F11可进入汇编语言调试状态。C++程序设计精要教程华中科技大学学习指导与习题解答第2章类型、常量及变量本章重点理解标识符、关键字、运算符、分割符的区别与联系。例如,运算符同时是分隔符。理解类型、变量、函数的定义方法。理解预定义类型与自定义类型(如结构与联合)。理解算术运算和类型解析的优先级和结合性,理解类型自动转换的方法。理解传统左值与传统右值的区别与联系。理解有址引用&、与无址引用&&的用法与注意事项。理解指针、数组、结构与联合的用法。理解不同数据类型变量的初始化方法。第2章类型、常量及变量学习指导标识符:由字母或下划线开始,紧接字母、数字或下划线组成的有限长度序列。关键字:也称保留字,由程序设计语言定义或保留的特定标识符,用于指导编译器进行语法分析。分割符:分隔符用于分割标识符或者保留字。运算符如+也是一种分割符,空格作为分割符它不是运算符。预定义类型:是由程序设计语言预先定义好的数据类型,如bool、char、short、int、long、longlong、float、double、longdouble等类型。自定义类型:即程序员自己定义的类型,如枚举enum、结构struct以及联合union等类型。变量:用于存储特定类型数值的标识,在内存会分配该类型相应字节数的存储单元。函数:根据给定参数信息完成特定任务的一段程序。优先级和结合性:算数运算、位运算与逻辑运算有不同的优先级和结合性。与加法运算自左向右结合不同,赋值运算在优先级相同(连续赋值如a=b=3)时自右向左结合,即先算b=3再算a=b。第2章类型、常量及变量学习指导类型转换:在进行算术运算时,字节数少的类型如char会自动向字节数多的类型转换,有符号类型自动向无符号类型转换。例如’0’+2=48+2=50。50是字符’2’的ASCII码值。由于数字字符连续编码,所以可以将数字’2’通过’2’-‘0’=2转换为整数2。数字’0’的ASCII码值为48。传统左值:
能够出现在等号左边的值或者表达式。例如,对于”intx=2;”,x、++x都是传统左值,而x++是传统右值。”++x=5;”的运算顺序为:(1)x=x+1;(2)x=5;而”y=x++;”的运算顺序为:(1)
y=x;(2)x=x+1;而x=2也是左值,因此可有(x=2)=4;传统右值:
能出现在等号右边的值或表达式。常量只能出现在等号右边,不能出现在等号左边。上例x既能出现在等号左边,又能出现在等号右边。由此可见,传统左值是传统右值,反之不成立。有址引用:被引用实体分配了内存的引用。intx=2;int&y=x;constint&z=2;//引用2生成的匿名变量无址引用:被引用实体未分配内存的引用。int&&a=2;double&&b=sin(2);constint&&c=2;第2章类型、常量及变量学习指导指针:指针变量用于存储内存单元的地址。而该地址可能某个变量的地址,该内存单元存储的值是该变量的值。数组:所有元素都具有相同数据类型的若干存储单元,这些存储单元合并称为一个数组。结构:每个元素独占内存组成的若干存储单元,这些存储单元合并称为一个结构。联合:所有元素共享同一块内存中的存储单元,这一存储单元被称为一个联合。类型解析:对于类型表达式中的运算符,优先级高的运算符先解释,优先级相同时按结合性规定的顺序进行运算。例如,对于int*f()应向解释括号,因为()的优先级比*高;对于char**p应根据结合性先解释右边的*。C++程序设计精要教程华中科技大学学习指导与习题解答第3章语句、函数及程序设计本章重点理解各种语句的用法,特别是分支语句和循环语句的用法。理解函数的作用域、inline函数、constexpr函数、consteval函数的用法。理解函数重载的定义方法及实现方法。理解#include的含义、以及extern说明变量和函数的方法。理解函数的默认值参数、引用参数、省略参数。理解函数的返回值及存储位置。理解线程互斥与线程本地变量。第3章语句、函数及程序设计学习指导顺序语句:包括值表达式语句、函数调用语句等顺序执行的语句。分支语句:包括if语句、选择语句和switch语句。选择语句即?:运算符构成的语句。循环语句:包括for、while、do-while等语句。do-while语句先执行循环体再检查循环条件。对于容器类变量,C++引入枚举器可遍历容器中的每个元素:inta[8];for(inti:a)printf(“%d\t”,i);转移语句:包括goto、continue、break等语句。continue立即进行下次循环,break跳出本层循环、或跳出本switch语句。值表达式:由数值及运算符构成的表达式。加上分号后构成值表达式语句,由等号构成的语句称为赋值语句。常见语句:(1)赋值语句x=x+3;(2)结果为传统右值的x++;结果为传统左值的++x;(3)x+=3;等价于x=x+3。结果为传统左值意味可继续赋值:(x=x+3)=4;++x=4;
(x+=3)=4;使用圆括号是为了提高优先级,否则不用。(4)y=x>0?1:-1;等价于if(x>0)y=1;elsey=-1;goto语句:VS2019可在函数内任意转移,前提是转移位置的相关变量已被初始化。第3章语句、函数及程序设计学习指导C作用域:C语言从小到大可分为语句、块、函数、文件、程序等作用域。如x=3中的常量的作用域为赋值语句;复合语句、循环体的作用域为块作用域,块可以嵌套;函数的作用域即函数体;文件作用域为当前.cpp文件,程序作用域为所有.cpp文件。变量的作用域至少是块以上。C++作用域:变量可能是类的对象,而类或对象的成员的作用域从小到大可分为语句、块、函数、派生类成员、基类成员等;然后进入变量所在的作用域,即面向过程的C语言的作用域。生命期:变量或常量从产生(初始化)到死亡的期间。全局变量的生命期是整个程序,static变量的生命期是从初始化开始到整个程序结束,函数参数及其局部非static变量的生命期是函数运行期间。常量的生命期是当前语句执行期间。内联函数:即inline函数,编译后可用其函数体直接替换其函数调用语句,以达到减少调用开销提高程序执行效率的目的。被定义为inline的内联函数,若编译后不用其函数体替换其函数调用语句,继续使用函数调用则称为内联失败(不报错)。若函数内有分支、循环、调用语句则通常导致内联失败,取一个inline函数的地址也会导致内联失败。第3章语句、函数及程序设计学习指导constexpr函数:若提供常量作为函数调用的实参,在编译时可能计算出常量值的函数。consteval函数:编译时必须计算出常量值的函数。函数重载:函数名称相同而参数个数或类型有所不同的同名函数。重载函数时,不能仅仅返回类型不同、而其它皆相同。C++函数编译为汇编代码后,参数类型成为函数名的一部分。#include:用于将.h文件的内容拷贝到其出现位置,.h文件通常用于定义类型、说明变量和函数。extern:用于说明变量和函数,同一变量和函数可被说明多次。.h文件常包含多个extern。变量说明:描述变量名称及其类型。变量定义=变量说明+初始化(此时必定分配内存)。函数说明:描述返回类型、函数名及其参数类型。函数定义=函数说明+函数体(此时必定分配内存)。参数默认值:函数参数可指定默认值,调用时若不传递实参则用默认值作为实参。intf(intx=2,inty=3){returnx+y;}//不用默认值:可用f(2,3)及f(4,5)调用//可用f()调用,等价于f(2,3);用f(4)调用,等价于f(4,3);//可以f(),f(int)和f(int,int)的形式使用,相当于同时定义了3个函数,若为构造函数如何?第3章语句、函数及程序设计学习指导voidg(int
&x){
x=8;} //引用类型的变量和参数被编译为汇编语言的指针voidmain(){inta=3;g(a);} //a=8:通过引用参数x,可以修改主调函数的实参a的值
intprintf(constchar*f,
…);
//省略参数…可出现任意个任意类型实参:printf(“%d”,2,3,4);函数返回值:可为传统左值或传统右值。intf(); //返回传统右值:不可f()=3。结果存放在EAX寄存器int&g(); //返回传统左值:g()=3;constint&h();//返回传统右值:不可h()=3int&&k(); //返回传统右值:不可k()=3constint&&m();//返回传统右值:不可m()=3线程互斥:即线程的部分代码不能并发执行。可通过lock/unlock实现互斥,也可通过作用域锁std::lock_guard实现互斥,作用域锁在退出其作用域时自动解锁,不管是否正常退出。线程本地变量:使用thread_local定义,同名变量在每个线程启动后,会为其分配独立的不同的内存。非线程本地变量的内存会被多个线程共享,其值是不可意料的。
C++程序设计精要教程华中科技大学学习指导与习题解答第4章C++的类本章重点理解类(class、struct、union)的定义方法和面向对象的基本概念。理解构造函数、析构函数的用途。理解显式调用、隐式调用。理解数据成员、成员函数、类型成员及其访问权限。理解私有成员、保护成员、公有成员的作用域。理解实例函数成员的隐含参数this。理解对象初始化的一般过程。理解编译生成默认构造函数与析构函数的前提。理解内联成员函数的作用域,以及new和delete用于对象内存分配的方法。理解对象的内存布局。第4章C++的类学习指导类的定义:可用class、struct、union定义类。对于class定义的类,进入类体{}时默认访问权限为private。为了兼容C语言,对于struct和union定义的类,进入类体{}时的默认访问权限为public。类体成员:包括类型成员、数据成员和函数成员。成员的访问权限可为private、protcted、public。private成员仅本类的函数成员可访问,protected成员仅本类及其派生类的函数成员可访问,public成员可被任意函数访问。若派生类函数成员为基类友元,则可访问基类的任何成员。类型成员:定义的服务于当前类的新类型,包括class、struct、union定义的(嵌套)类。数据成员:用于描述对象的属性。例如,人类的年龄属性。函数成员:用于对象属性的操作,例如,将年龄增加1岁的函数成员。构造函数:用于完成对象的初始化,包括基类和数据成员的初始化(通常由程序员完成),以及多态信息的维护(必定由编译完成)。析构函数:用于完成对象初始化时申请的资源的释放。对象生命期结束,编译将自动调用析构函数。实例函数成员:类中未使用static定义的函数成员,都是有隐含参数this的函数成员。第4章C++的类学习指导this参数:调用实例函数成员的对象,其地址将传递给this参数。传递给this时,实参应同*this的类型一致。构造函数和析构函数的this形参类型是固定的。对象初始化:由构造函数完成,初始化其基类和数据成员。类有虚函数时,编译程序会自动维护多态信息。如果类有私有成员且未定义任何构造函数,或类有私有只读成员或引用成员,编译程序将自动生成实参表无参的构造函数。若未定义析构函数,编译可自动为类生成析构函数。内联函数:在类体里也可定义inline函数,内联函数也可能内联失败。内联函数的作用域为当前类所在的.cpp文件。用new为对象分配内存:分配完毕,编译程序会自动调用构造函数。对于对象数组默认调用无参构造函数多次,但也可以列出实参调用有参构造函数多次。
使用delete:使用new分配的对象,一定要由程序员主动调用delete,进行析构和释放对象内存。在释放对象内存之前,编译会自动调用对象的析构函数。对于对象数组应使用delete[]的形式为所有对象调用析构函数。对象内存布局:若对象的数据成员之间没有空闲字节,则称这种布局为紧凑布局,否则为松散布局。C++程序设计精要教程华中科技大学学习指导与习题解答第5章成员及成员指针本章重点理解实例数据成员与静态数据成员的区别。理解mutable定义的机动实例数据成员的用法。理解实例数据成员指针的用法。理解静态数据成员指针的用法。理解实例函数成员与静态函数成员的区别。理解实例函数成员指针与静态函数成员指针的区别。第5章成员及成员指针学习指导实例数据成员:类中未使用static定义的数据成员。这种成员是对象即实例的一部分。静态数据成员:类中使用static定义的数据成员。这种成员不是对象的一部分,依赖于类存在。机动成员:使用mutable定义的实例数据成员。当对象为只读对象时,其机动成员可写。实例数据成员指针:指向实例数据成员的指针,是相对其对象首址的偏移量。因此,这种指针不能随意“移动”,否则可能移动到访问权限不同的实例数据成员。它也不能和其它类型进行相互转换,否则通过转换及运算可间接实现“移动”。实例数据成员指针声明必须使用“类名::*”。通过“对象.*实例数据成员指针”访问该对象相应的实例数据成员的值。静态数据成员指针:指向静态数据成员的指针。静态数据成员指针是指向类或对象静态数据成员的真正意义上的指针。这种指针可以随意“移动”,也能和其它类型进行相互转换。静态数据成员的声明同C语言普通数值指针一样。提倡通过“*数据成员指针”访问该类相应静态数据成员的值。第5章成员及成员指针学习指导实例函数成员指针:指向有this参数的实例函数成员的指针。同理,这种指针不能随意“移动”,也不能和其它类型进行相互转换。静态函数成员指针:指向无this参数的静态函数成员的指针。静态函数成员指针是指向类或对象静态函数成员的真正意义上的指针。提倡通过“*函数成员指针”访问该类相应静态函数成员。上述指针的区别:在说明、定义和调用时,所有形式或格式不同。C++程序设计精要教程华中科技大学学习指导与习题解答第6章继承与构造本章重点了解单继承类的定义方法。理解基类成员继承到派生类后的访问权限变化。了解using基类成员的方法。了解派生类对象的构造或初始化顺序。了解派生类对象的析构顺序。理解派生类对象的内存布局。第6章继承与构造学习指导派生类的定义:使用class或struct定义。classB:A{
int
x;
};等价于structB:privateA{private:intx;};structB:A{intx;};等价于classB:publicA{public:
int
x;
};注意union不能定义派生类或作为基类。访问权限变化:基类成员继承到派生类后,访问权限可能同基类原先定义的访问权限不同。其变化机理有“筛孔效应”。若派生类函数不是基类友元,则它不能访问基类私有成员。派生类函数总能访问基类的保护成员和公开成员。继承方式基类成员访问权限privateprotectedpublicprotectedprivateprotectedprotectedpublicprivateprotectedpublic第6章继承与构造学习指导using基类成员:在派生类的private区域using基类特定成员,则基类成员继承到派生类后的访问权限指定为私有的;同理,在派生类的protected区域using基类特定成员,则基类成员继承到派生类后的访问权限指定为保护的;在派生类的public区域using基类特定成员,则基类成员继承到派生类后的访问权限指定为公开的。using注意事项:被using的基类特定成员必须是派生类所有函数可访问的,且using之后派生类不得定义同名的数据成员。派生类构造顺序:(1)优先构造虚基类;(2)次优先构造直接基类;(3)按定义顺序构造或初始化派生类的数据成员;(4)执行派生类的构造函数体。若其基类或虚基类又是一个派生类,则递归上述过程,但同一颗派生树中同名虚基类只构造一次。对于单继承来说,没有必要定义虚基类。派生类析构顺序:与构造顺序完全相反,先执行析构函数的函数体,然后在析构数据成员时,按数据成员定义顺序的相反顺序析构数据成员。以此类推其直接基类或者虚基类。派生类内存布局:不管派生类函数能否访问基类成员,基类所有成员作为整体在派生类自定义数据成员的前面。基类及派生类所有静态数据成员及函数成员不会出现在对象的内存块中。C++程序设计精要教程华中科技大学学习指导与习题解答第7章可访问性本章重点了解作用域运算符“::”的用法。理解面向过程的作用域。理解面向对象的作用域。了解名字空间的用法。了解成员的隐藏与覆盖。理解友元的定义与用法。第7章可访问性学习指导作用域运算符“::”:作为单目运算符时,用于访问全局变量和模块变量,以及外部非成员函数。模块变量即函数外如main外用static定义的变量。作为双目运算符时用于访问类的成员、枚举成员以及名字空间成员。面向过程作用域:即C语言的作用域,从小到大可分为语句级、块级、函数级、文件级以及程序级。常量属于语句级,变量属于块级或函数级,参数仅属于函数级,函数外定义的static变量属于文件级,函数外定义的全局变量属于程序级。面向对象作用域:即类相关的作用域,从小到大可分为语句级、块级、函数级、派生类级(成员)、基类级(成员)、虚基类级(成员)。当面向对象作用域找不到时,进入面向过程作用域寻找标识符。名字空间:只能在类和函数外使用namespace定义,可嵌套定义、分多次定义同一个名字空间,可定义名字空间及其子空间的别名。格式为”namespace名字空间名{成员定义};”。名字空间的使用:格式为”usingnamespace名字空间名”,不会将成员引入当前作用域,因此,可在当前作用域定义同名的标识符。可在任何函数内外using,不可在类体中使用。特定名字空间成员的使用:格式为”using名字空间名::成员名”,会将成员引入当前作用域,因此,不可在当前作用域定义同名标识符。Using范围限制同上。第7章可访问性学习指导基类成员的隐藏:通过派生类对象不能访问基类定义的和派生类成员同名的成员。例如,基类成员继承到派生类后成为派生类的私有或保护成员,在main函数不是派生类友元函数时,通过main中定义的派生类对象不能访问基类定义的和派生类成员同名的成员。基类成员的覆盖:通过派生类对象可以访问基类定义的和派生类成员同名的成员。此时,可通过“派生类对象名.基类名::成员名”访问被覆盖的基类成员。友元:可通过friend将成员函数和非成员函数定义为某个类的友元,从而使其可以访问该类的所有成员。如将类A的所有函数定义为类B的友元,则称A为类B的友元类。友元不具备传递性:若A为B的友元,B为C的友元,不表示A也是C的友元。在类中定义友元函数时,可同时定义其函数体,该友元函数自动成为内联函数。不应在类中定义函数main为友元的同时定义其函数体,因为main不应该被内联(内联的作用域为模块级,内联成功意味main将被删除,即不存在main的入口地址)。派生类(函数)成为基类的友元:则可以访问基类的所有成员,否则只能访问基类的保护和公有成员。C++程序设计精要教程华中科技大学学习指导与习题解答第8章多态与虚函数本章重点了解虚函数的定义方法。理解自动成为虚函数所需的返回类型、对应参数类型的”相容”性要求。理解虚函数的晚期绑定与构造函数的关系。理解纯虚函数与抽象类的用法。了解有虚函数的对象的内存布局。理解虚析构函数的作用。第8章多态与虚函数学习指导虚函数定义:使用virtual定义的有隐含参数this的实例函数成员。构造函数有this参数,但它无需表现出多态特性,故不允许将其定义为虚函数。其它实例函数成员均可定义为虚函数,定义为final的函数必须同时定义为虚函数。类的相容性:类的类型“相容”是指一种类的值可相对安全地转换为另一种类的值。比如子类对象可以安全地转换为父类对象,子类对象指针可以安全地转换为父类对象指针。若基类定义了虚函数,则派生类的同名函数必须满足函数原型相容(包括对应参数和返回类型相容)才能自动成为虚函数。晚期绑定:程序运行时由程序自己完成的绑定,执行的绑定代码是由编译程序预先生成的。构造对象或对对象进行类型转换(如转换为基类)时,会根据对象或要转换的实际类型,在对象内部填入适当的虚函数入口地址表指针,指向与当前对象类型相符的虚函数入口地址表。因此,通过对象指针找到这个对象内部指针,进而找到与当前对象类型相符的虚函数调用,从而表现出与对象类型一致的多态行为。第8章多态与虚函数学习指导纯虚函数:即无法定义或没有函数体的虚函数,定义格式为“virtual类型函数名(参数)=0”。抽象类:包含纯虚函数的类:继承后未在派生类覆盖定义来自基类的纯虚函数,或者是派生类自己定义了新的纯虚函数。抽象类A不能产生对象,例如,不能定义Aa;Af();voidg(A)等;但是可以定义A*p;A&q=…;
A&&r=…;
A*h();A&k();A&&m();voidn(A*);voido(A&);voidr(A&&);。抽象类也不能通过new产生抽象类对象。包含虚函数对象内存布局:如前所述,为支持虚函数的多态和晚期绑定,对象内部多了一个虚函数入口地址表指针。该指针的值随着对象类型的变化而变化,例如,构造和析构时的对象类型变化。虚析构函数:若基类析构函数定义为虚函数,则派生类析构函数也自动成为虚函数。将析构函数定义为虚函数,可以在一定程度上防止内存泄漏。例如,对于“deletep”,p定义为父类指针但实际指向子类对象时,若父类的析构函数不是虚函数,将对子类对象调用父类对象的析构函数,可能导致子类对象申请的部分资源未予释放,从而可能造成内存泄漏。C++程序设计精要教程华中科技大学学习指导与习题解答第9章多继承与虚基类本章重点了解多继承派生类的定义方法。理解为什么要引入虚基类。学会解决成员访问二义性的方法。理解多继承类的构造与析构过程。了解多继承类对象的内存布局。第9章多继承与虚基类学习指导多继承派生类:使用class或struct定义多继承派生类,如“class派生类名:继承方式1类名1,继承方式2类名2,…{…};”,其中“继承方式”为可选项,对于class定义的类默认为private,对于struct定义的类默认为public。每个“类名”代表一个基类,该基类可能是已经定义好的派生类。如此形成一棵派生树,树根和中间节点均为派生类,而叶子节点为基类。虚基类:在“继承方式”前后可以使用“virtual”定义其基类为虚基类。在派生树中,不同分支的中间结点可能同名,不同分支的叶子结点也可能同名。这些同名节点逻辑上有多个,物理上可能仅有一个,若物理上仅有一个,则应把同名节点定义为虚基类,以实现到唯一物理实基类的映射。水陆两栖车船汽车游船车轮引擎引擎螺旋桨第9章多继承与虚基类学习指导成员访问:在最终定义的派生树中可能存在多个同名数据或函数成员:派生类自定义的、不同基类继承来的。当使用派生类对象访问同名成员时,优先访问派生类自定义的同名成员,因为该成员比基类成员的作用域小。一个基类成员可以成为多个派生类的成员,故基类成员作用域更大。成员访问二义性:若派生类C未定义成员x,而从C的两个直接基类A、B继承了两个成员x,此时用C的对象c访问x即“c.x”就会出现二义性,因为A::x和B::x的访问优先级相同。此时,应用“c.A::x”或者“c.B::x”访问基类A或B的成员x。派生类构造顺序:派生类可能存在多个不同虚基类、多个不同直接基类以及多个不同数据成员。在初始化派生类对象时按4个优先级执行:(1)构造自根至叶自左至右搜到的所有分支的第一个虚基类;(2)构造自左至右定义的所有直接基类;(3)初始化先后定义的所有数据成员;(4)执行该派生类的构造函数体。若其中的基类又是派生类则重复上述过程,但同一棵派生树的同名虚基类仅构造一次(它们映射到唯一物理实基类)。对象内存布局:同名虚基类在派生类对象中只有一份内存(多个虚基类映射到唯一物理实基类)。C++程序设计精要教程华中科技大学学习指导与习题解答第10章异常与断言本章重点了解异常的定义方法。理解异常的抛出与捕获过程。学会catch异常捕获参数的布置方法。理解函数的异常接口定义方法。了解断言的使用方法。第10章异常与断言学习指导异常定义:异常是一种意外中断程序正常处理流程的事件。异常既可以被硬件引发,又可以被软件引发,软件引发用throw语句。异常定义:格式为“try{正常流程程序}catch(异常类型形参){异常处理程序}…catch(异常类型形参){异常处理程序}”。正常流程程序可以直接throw一个异常,也可以由其调用的函数体内throw一个异常。异常类型:可以是简单类型、类、函数、Lambda表达式等任意类型:包括数值类型与函数类型。捕获过程:由一系列catch依次匹配其形参捕获。一个try后面可跟多个catch,当从”正常流程程序”中throw一个异常时,该异常的类型将和每个catch的“异常类型”匹配,一旦匹配成功紧随其后的其它catch将被忽略。如果没有一个catch匹配成功,则跳过本层的后续所有语句,去匹配包含该try-catch语句的上一层的try的catch。若主函数main也没有捕获该异常,则执行本程序的终止函数。第10章异常与断言学习指导catch布置:当出现多个catch时,前面的catch机会优先。因此,若把父类异常的catch放在子类异常的catch前面,父类异常catch就会捕获父类异常和所有子类异常,从而造成后续子类异常catch没有捕获机会,因此,子类异常catch应放在父类异常catch的前面。注意,子类异常catch是不会捕获父类异常的,这样后面的父类异常catch还有捕获父类异常的机会。catch布置:对于catch(constint*),它能捕获constint*和int*两种类型的异常。因此,catch(int*)应放在catch(constint*)的前面,catch(int*)不会捕获constint*类型的异常。同理,catch(int*)应放在catch(volatileint*)的前面,catch(int*)不会捕获volatileint*类型的异常。但是,catch(constvolatileint*)能够捕获constint*、volatileint*、int*类型的异常,所以它应放在前述所有整型指针的catch后面。catch布置:由于catch(constvolatilevoid*)能捕获任何指针类型的异常,因此,它应放在所有catch(指针类型形参)之后。省略参数…能够匹配任何类型的异常,所以catch(...)应放在所有catch(异常类型形参)的后面。第10章异常与断言学习指导异常接口:异常接口用于声明函数抛出但自己不捕获的异常,格式为“函数头throw(异常类型1,异常类型2,…,异常类型n)”。例如,intf()throw(constchar*)声明f不处理它抛出的constchar*异常。如果函数f不抛出异常、或者它处理了所有它抛出的异常,则可以定义f为如intf()throw()、intf()throw(void)或者intf()noexcept。如果函数没有定义异常接口,则它可能抛出任何异常。断言:断言是一种检查程序编译或执行条件是否满足的机制。静态断言:静态断言static_assert在编译时检查程序的编译条件是否满足,如不满足则输出断言表达式并停止编译。动态断言:动态断言assert在运行时检查程序的执行条件是否满足,如不满足则输出断言表达式并停止执行。断言实例:static_assert(size(int)==4);
assert(x>4);
C++程序设计精要教程华中科技大学学习指导与习题解答第11章运算符重载本章重点了解传统左值与传统右值运算符的区别。了解运算符重载函数的分类方法。了解既可重载为单目又可重载为双目运算符的方法。了解深拷贝构造函数与移动构造函数的应用场景。了解深拷贝赋值与移动赋值的应用场景。了解特殊运算符如++、--、->与()的重载方法。第11章运算符重载学习指导运算结果:可分为传统左值与传统右值。传统左值结果可被继续赋值,否则便是传统右值结果。对于intx,++x、--x、(x=3)、(x+=3)等都是传统左值结果,而x++、x--、x+3等都是传统右值结果。重载函数分类:(1)5个不可重载如sizeof、.、.*、::和三目运算符?:。(2)只能重载为实例函数成员=、–>、()、[]。(3)不能重载为实例函数成员new和delete。(4)其他都不能重载为静态函数成员。单双目运算符:+、-、*等:例如,-既可单目减如-5;又可双目减如5-3。所有运算符重载都要求至少有一个参数代表一个对象,注意对象指针(除this外)不能代表一个对象,对象数组也不能代表。单双目的重载:单双目运算符基本属于上述第(4)种。不能重载为静态函数成员:即可重载为实例函数成员和非成员函数。例如,对于类A的单目减,若重载为实例函数成员(有this),建议格式为“Aoperator-()const”;若重载为非成员函数(无this),建议格式为“Aoperator-(const
A&)”。对于类A的双目减,若重载为实例函数成员(有this),建议格式为“Aoperator-(const
A&)const”;若重载为非成员函数(无this),建议格式为“Aoperator-(const
A&,constA&)”。赋值运算重载:对于其第一个操作数可被修改、返回结果为传统左值的等号,建议重载格式为深拷贝和移动赋值两种形式:(1)A&operator=(constA&);(2)A&operator=(A&&);第11章运算符重载学习指导++、--重载:分为前置和后置运算,都修改第1操作数。前置运算先运算、结果为传统左值,后置运算先取值作为结果(传统右值),后运算改变第1操作数。前置++:
(1)作为实例成员函数重载:A&operator++();(2)作为非成员函数重载A&operator++(A&);后置++重载为双目形式:
(1)作为实例成员函数重载:Aoperator++(int);(2)作为非成员函数重载Aoperator++(A&,int)。()的重载:(1)重载为函数调用,可为任意目“类型operator()(...)”等;(2)重载为类型转换“(作为函数名的类型表达式如int)”,重载时无返回类型“operatorint()const”。->的重载:本为双目但重载为单目形式,通常返回T*的指针。
如T*operator->()等实例函数成员。构造函数重载:深拷贝构造A(const
A&),常在用变量作实参调用函数如f(A
x)时,用深拷贝构造函数构造形参x;也可用在老变量a定义新变量时如Ax(a)调用深拷贝构造。移动构造,常在用常量(对象)作实参调用函数如g(A
x)时,用移动拷贝构造函数A(A&&)构造形参x;也可用在用常量(对象)定义新变量x时如Ax(A(3))。C++程序设计精要教程华中科技大学学习指导与习题解答第12章类型解析、转换与推导本章重点了解简单类型自动转换的默认顺序与转换结果。了解cast系列类型转换的用法。了解typeid,explicit等的用法。了解自动类型推导auto与类型提取decltype的用法。了解Lambda表达式的用法。第12章类型解析、转换与推导学习指导简单类型自动转化:自动从字节数少的类型向其对应的无符号类型、或字节数更多的类型转换。强制类型转换结果通常为传统右值,例如,对于intx=3;语句”((short)x)=5;“是错误的。static_cast类型转换:static_cast转换不做动态类型检查,故不保证运行时类型转换后的安全性;也不能对原始类型添加或去掉const或volatile。const_cast类型转换:const_cast转换不做动态类型检查,故不保证运行时类型转换后的安全性;但可以对原始类型添加或去掉const或volatile。dynamic_cast转换:dynamic_cast转换时进行动态类型检查,可保证运行时类型转换后的安全性,如不安全则便不能成功转换:转换失败时抛出异常或得到nullptr结果。基类向派生类转换时基类必须有虚函数。reinterpret_cast转换:重释转换主要用来处理地址或指针,例如,变量名到指针或引用的转换,实例成员地址到实例成员指针的转换,有址引用与无址引用之间的转换,指针与足够大整数类型如int的相互转换。第12章类型解析、转换与推导学习指导typeid:在#include<typeinfo>之后,可用typeid获得表达式或类型的类型信息,如typeid(3).name()的结果为“int”。可用typeid检查值是否为类B的实体或对象,再向目标类型B转换比较安全,例如对于“classA{virtualvoidf(){}};structB:A{}b;A*p=&b;”,使用”if(typeid(*p)==typeid(B))B*q=(B*)p;“。explicit:如果不希望单个参数构造函数自动将其参数类型的表达式转换为对象,则可以在该构造函数的定义前面添加explicit说明。例如,classA{intx;public:explicitA(intx):x(x){};};类型推导:auto可以推导变量、参数和函数的返回类型;不能假设被推导的变量、参数、或返回类型不变、再出现在相关的初始化表达式中,例如,定义“autox=x+1;”是错误的。类型提取:decltype可以提取表达式的类型,可以出现在任何需要类型的地方,被提取的表达式一定是其类型可被计算的表达式。Lambda表达式:Lambda表达式声明格式为“[捕获列表](形参列表)mutable异常说明->返回类型{函数体}”。其捕获列表不能捕获永久变量,只能捕获栈上的变量或函数参数,包括隐含参数this指针,不包括全局变量、静态变量和类的数据成员。如果没有捕获任何外部变量,则Lambda表达式被视为“准函数”,否则被视为匿名类的“准对象”。若Lambda表达式中出现了mutable,则捕获的非引用(即捕获变量时,不用&而是用=)和非只读的外部变量可被视为匿名类的机动数据成员。C++程序设计精要教程华中科技大学学习指导与习题解答第13章模板与内存回收本章重点了解变量模板的定义及实例化方法。了解函数模板的定义及实例化和特化方法。了解类模板的定义及实例化和特化方法。了解模板的类型参数省略和设定默认类型的方法。了解std::initializer_list等常用模板类。了解内存垃圾自动回收的方法。第13章模板与内存回收学习指导变量模板:变量模板是一种用多种类型定义同名变量的机制,通过指定类型参数对变量模板实例化,为变量模板生成不同类型的多个实例变量。可以使用“template类型表达式变量名<类型表达式>”的形式进行强制实例化,也可以通过在表达式中使用“变量名<类型表达式>”的形式隐式实例化。函数模板:是一种用来抽象大量计算过程类似的同名函数的机制,可以使用“template返回类型函数名<类型实参>(形参列表)”强制实例化,也可以在表达式中使用“函数名<类型表达式>(…)”调用函数隐式实例化。类模板:类模板也称为类属类或参数化的类,用于为相似的类定义一种通用类模式。可采用“templateT<类型实参列表>”的形式强制实例化,也可在定义变量、参数和函数返回类型时使用“类名<类型实参>”隐式实例化。可以使用如usinghandle_type=std::experimental::coroutine_handle<promise_type>或typedef为实例类定义别名。省略类型参数:也称为可变类型参数,即可以有任意个任意类型的类型参数。通常使用递归展开定义模板。第13章模板与内存回收学习指导类型参数默认值:即可以为某个类型参数指定默认类型。如template<typenameT=int>为
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 车间雨污分流改造实施方案
- 颈椎腰椎推拿操作规范手册
- 疼痛症状评估分级诊疗规范
- 颈椎病严重程度评估规范指引
- 脊柱矫正正骨复位流程指引
- 小麦一喷三防药剂喷施方案
- 农用种子质量检测技术规程
- 孕期营养配餐搭配制作规范
- 体态评估检查标准操作指引
- 家政会员卡充值消费管理规范
- JG/T 353-2012工业滑升门
- T/CECS 10022-2021埋地用改性高密度聚乙烯(HDPE-M)双壁波纹管材
- 2025高考长郡中学物理小题冲刺训练+题目
- 屋面防水监理单位工程质量评估报告
- 个人按揭合同范例
- 2025年山东海化集团招聘笔试参考题库含答案解析
- 《公路全封闭声屏障结构设计指南》
- 在《人民报》创刊纪念会上的演说 教学课件
- 电工技术基础与技能单选题100道及答案
- 医学课件伤寒论讲义
- DB11∕T 1559-2018 碳排放管理体系实施指南
评论
0/150
提交评论