[C++ Programming] Chapter 1~9: Summary of common knowledge points

Table of contents

1. Introduction to C++ language

2. Basic concepts of object-oriented 

3. Advanced classes and objects 

4. Operator overloading 

5. Inheritance and derivation of classes 

6. Polymorphism and virtual functions 

7. Input/output stream 

8. File operations 

9. Function templates and class templates 



1. Introduction to C++ language

Knowledge point name content

A brief history of the development of C++ language
★★
1. C language is the predecessor of C++ language. C++ language was obtained based on further expansion and improvement  of C language.
2. A program written in C++ language is called a source program. The source program must be translated into machine language by a C++ compiler before it can be executed.
(1) Generally, it needs to be
edited, compiled, connected, and run .
3. The main characteristics of the C++ language are reflected in two aspects:
(1) It is an inheritance of the C language and is as compatible with the C language as possible. It not only maintains the simplicity and efficiency of the C language, but also can carry out structured programming like the C language. It also enhances the C language's handling of types.
(2) Added object-oriented features.

Features of C++ language
★★
1. Compared with C language, the advantages of C++ language:
(1) In terms of the stability of program operation, C++ language is safer. It supports procedural programming, object-oriented programming and generic programming.
(2) The C++ language can run on a variety of platforms, such as Windows, MAC operating systems and various versions of UNIX.
(3) The object-oriented concept is added to the C++ language , and the program structure of C++ is very different from that of the C language.
Basic
input/output
★★★★★
1.  Objects in C++ classes :
(1)
cin  : The operator is >>, used for keyboard input. Function scanf(); input stream class istream
(2)
cout  : The operator is <<, used for screen output. Function printf(); output stream class ostream
2. The stream extraction operator and the stream insertion operator are composed of two consecutive symbols, and there cannot be other symbols in the middle.
3. 
%c  is the format control character for outputting a single character . %s  is the format control character of the output string . 4. When using cin and cout in the program, the header file <iostream>  needs to be included in the program . 5. The statement ends with a semicolon ";".

Header files and
namespaces
★★★★★
1. Commonly used header files include the following:
(1) Standard input and output stream:  <iostream>.
(2) Standard file stream:  <fstream>  .
(3) Standard string processing function: 
<string>  .
(4) Standard mathematical function: 
<cmath> .
Programmers can also define their own header files and 
include them in their programs using the #include  directive. Typically, angle brackets are used to enclose system-provided header files , and double quotes are used to enclose programmer- defined header files . 2. There are two syntax formats for using statements to reference identifiers of other namespaces: (1) using namespace name::identifier; (2) using namespace namespace name;



Casting
operator
★★
1. The data type levels from low to high are: char→int→float→double .
(1) When different types of quantities are subjected to mixed arithmetic operations, the system automatically performs reasonable type conversion.
(2) The compiler will automatically convert
low-level types to high-level types .
2. Use the forced type conversion operator 
static__cast  or  const__cast  to convert.
(1) static__cast converts one data type into another data type, format: static__cast <type name> (expression)
static__cast can also be omitted.
(2) const__cast removes the constantness of pointers and references, but cannot remove the constantness of variables: const__cast <type name> (expression)

Default values ​​of function parameters
★★★★★
1. The C++ language stipulates that when providing default values, they must be provided in order from right to left, that is, the formal parameters with default values ​​must be at the end of the formal parameter list.
(1) If a formal parameter has no default value, then all formal parameters to the left of it cannot have default values.
2. When calling a function, the actual parameters of the calling function and the formal parameters of the called function are matched from left to right.
(1) If the number of actual parameters is equal to the number of formal parameters, they correspond one to one.
(2) If the number of actual parameters m is less than the number of formal parameters n, then the first m formal parameters in the function prototype parameter list correspond to the m actual parameters, and the following nm formal parameters use the default values. Perform initialization.
3. Function without return value: The return statement without return value can only be used in functions whose return type is void.
(1) Functions with return values: The second form of the return statement provides the result of the function.  
(2) As long as the return type of the function is not void, each return statement within the function must return a value.
Passing of references and function
parameters
★★★★★
1. 引用相当于给变量起了一个别名。定义格式:类型名 &引用名=同类型的某变量名;
2. 在 C++ 中, 函数调用时参数的传递有两种方式:传值和传引用。
(1)
传值:实际上是传递对象的值
即将实参的值拷贝给形参。
在函数执行过程中,都是对这个拷贝进行操作的,函数执行完毕返回后,形参的值并不拷贝回实参,也就是说函数内部对形参的改变不会影响到函数外实参的值。
(2)
传引用:传递对象的首地址值
函数调用时,实参对象名传递给形参对象名,形参对象名就成为实参对象名的别名,即形参是对应实参的引用,它们是等价的,代表同一个对象,也可以看作是将实参的地址传递给了形参 。
const 与指
针共同使用
★★★★
1. C++ 语言也可以使用 const 限定访问权限,const 修饰指针变量时,基本含义如下:
(1)如果唯一的 const 位于符号 * 的左侧,表示指针所指数据是常量,数据不能通过本指针改变,但可以通过其他方式进行修改;指针本身是变量,可以指向其他的内存单元。
(2)如果
唯一的 const 位于符号 * 的右侧,表示指针本身是常量,不能让该指针指向其他内存地址;指针所指的数据可以通过本指针进行修改。
(3)在
符号 * 的左右各有一个 const 时,表示指针和指针所指数据都是常量,既不能让指针指向其他地址,也不能通过指针修改所指向的内容。
【助记 :可以简单地记住 const 的修饰规则:const 修饰其左侧的内容;如果 const 是本行的第一个标识符 ,则它修饰其右侧的内容 。 】
内联函数
★★★★
1. 引入了内联函数的目的:加快执行速度。
(1)定义内联函数时只需在函数头返回值类型的前面加上关键字 inline 
2. 内联函数的适用情况:
只有几条语句,且频繁调用的小函数
3. 在 C++ 中,除
具有循环语句、switch 语句的函数不能说明为内联函数外,其他函数都可以说明为内联函数 。
函数的重载
★★★★
1. 函数重载:是指在程序的同一范围内声明几个功能类似的同名函数。
(1)即前提是函数名相同。
(2)可提高代码可读性。
(3)
函数重载可使一个函数名具有多种功能,即具有“多种形态 ”,称这种特性为多态性。
2. 实现函数的重载必须满足下列条件之一:
(1)参数表中对应的
参数类型不同。
(2)参数表中
参数个数不同。
指针和动态
内存分配
★★★★
1. 指针变量中保存的是一个地址 ,有时也称指针指向一个地址。
2. 使用 
new 运算符动态申请的内存空间,需要在使用完毕释放。C++ 提供了 delete 运算符,用来释放动态分配的内存空间。
(1)使用 new 运算符实现动态内存分配。
p=new T;  其中,T 是任意类型名,p 是类型为 T* 的指针。
(2)使用 new 运算符还可以动态分配一个任意大小的数组:p=new T[N];  其中,是任意类型名,是类型为 T*的指针, N 代表数组元素个数 ”,可以是任何的值为正整数的表达式。
(3)C++ 提供了 delete 运算符,用来释放动态分配的内存空间,基本用法:delete 指针
3.  delete 释放动态对象数组时,实现为 delete []ptr;
4. 
数组的下标从 0 开始,含 n 个元素的数组的下标范围是从 0n-1 
用 string
对象
处理字符串
★★★★★
1. 字符常量:用单引号括起来的单个字符或转义字符。
(1)字符串常量:用双引号括起来。
2. 大小写字母 
ASCII 码差 32 。
3. 
string 类中的常用成员函数:
(1)int size() const;          返回当前字符串的大小
(2)int length() const;      返回当前字符串的长度
(3)bool empty() const;   判定当前字符串是否为空
(4)
find();                        返回 str 在字符串中第一次出现的位置 ,如果没找到则返回-1
(5)insert();                      在 p 位置插入字符串 S
(6)append();                   将字符串 s 连接到当前字符串的结尾处
(7)
substr();                     返回从 pos 开始的 n 个字符组成的字符串
C++语言的
程序结构
★★★
1. 程序中必须有且仅有一个主函数 main() ,这是程序执行的总入口。
2. C++ 程序中,仍沿用 C 语言的注释风格,即注释有以下两种形式。
(1)从
 /* 开始 ,到 */ 结束,这之间的所有内容都视作注释 。
(2)从
 // 直到行尾,都是注释。

二、面向对象的基本概念 

知识点名称 内容
结构化
程序设计
1. 在编写程序时,使用 3 种基本控制结构来构造程序:顺序、选择、循环基本控制结构。
面向对象
思想的提出
★★★★
1. 对象的一个实例。
(1)对象是类的一个具象,是对象的一个抽象。
2. 
面向对象技术把问题看成是相互作用的事物的集合,也就是对象的集合。
3. 
对象特性:一是状态(也称为属性);二是行为(也称为操作)。
(1)状态是指对象本身的信息,也称为属性;行为是对对象的操作。
4. 通过对事物的
抽象找出同一类对象的共同属性(静态特征)和行为(动态特征) ,从而得到的概念 。
5.
(1)
在结构化程序设计中,采用自顶向下、逐步求精及模块化的思想,将复杂的大问题层层分解为许多简单的小问题。
(2)面向对象的程序设计方式更接近于人们看待真实世界的情况。真实世界是由各类不同的事物组成的。
面向对象
程序设计
的特点
★★★★
1. 抽象在面向对象的程序设计方法中,将同一类事物的共同特点概括出来。
(1)对象的特点包括两个方面:属性和操作。
(2)C++ 中使用对象名、属性和操作三要素来描述对象。
2. 
封装:将对象的属性及实现细节隐藏起来,只给出如何使用的信息。
(1)将数据成员使用 private 关键字定义,则产生封装性。
3. 
继承就是在编写一个“新”类的时候,以现有的类作为基础,使得新类从现有类“派生 ”而来,从而达到代码扩充代码复用的目的。
(1)原来的类是基类,也称为父类或超类。
(2)新类是派生类,也称为子类
4. 
多态是指不同种类的对象都具有名称相同的行为,而具体行为的实现方式却有所不同。
类的定义
★★★★★
1. 标识符命名规则
(1)
字母数字下划线的组合,大小写敏感,但不能以数字开头,也不能和系统中使用的关键字完全相同。
2. 面向对象方法中的类,是对具有相同属性和行为的同一类对象的抽象描述,其内部包括
属性(本类的成员变量)和行为(本类的成员函数)两个主要部分,即类以数据为中心,把相关的一批函数组成为一体。
3. 类中定义的数据和函数称为这个
类的成员(数据成员和成员函数)
4. 类体外函数定义的前面必须用“
类名::”来限定,格式如下:
返回值类型 类名::成员函数名(参数列表)
{
    成员函数的函数体
}
程序结构
★★
1. .h 文件是头文件
2. 
.cpp 文件是源程序文件
3. C 源程序文件编译而成的目标文件的扩展名是 
.obj
4. 可执行代码的文件扩展名为 .exe
创建类对象
的基本形式
★★★
1. 使用“类名 *对象指针名 = new 类名;”创建对象时,调用无参的构造函数。
(1)如果这个构造函数是由编译器为类提供的,则类中成员变量不进行初始化。
2. 使用“
类名 *对象指针名 = new 类名();”创建对象时,也调用无参的构造函数。
(1)如果这个构造函数是由编译器为类提供的,则对类中的成员变量进行初始化。
访问对象的
成员
★★★★
1. 使用对象:如果变量 a 为结构体对象,且结构体内有元素 b,那么可以使用 a.b 的方式访问元素。
2. 
使用指针:如果变量 a 为结构体指针,且结构体内有元素 b,那么可以使用 a->b 的方式访问元素。
3. 
使用引用:访问成员时仍使用点操作符,即“引用名.成员名”。
访问范围说
明符的含义
★★★★★
1. private 私有的:使用它修饰的类的成员仅能在本类内被访问。(默认)
2. public 公有的:使用它修饰的类的成员可以在程序的任何地方被访问。
3. 
protected 保护的:它的作用介于 public 与 private 之间,使用它修饰的类的成员能在本类内及子类中被访问。
标识符的
作用域与
可见性
★★
1. 函数原型作用域:在声明函数原型时形参的作用范围就是函数原型作用域,最小的作用域
2. 
局部作用域:程序中使用相匹配的一对大括号括起来的一段程序称为块。
(1)作用域局限在块内的称为
局部作用域
3. 
类作用域:类可以被看成是一组有名字的成员的集合,类 X 的成员 m 具有类作用域,对 m 的访问方式有如下 3 种:
(1)
直接访问成员 m。
(2)在类外,通过表达式 
x.m 或者 X::m 来访问
(3)在类外,可以通过 
ptr->m 表达式来访问。
4. 
命名空间作用域:在命名空间内部可以直接引用当前命名空间中声明的标识符,如果需要引用其他命名空间的标识符,需要使用下面的方式:命名空间名::标识符名

三、类和对象进阶 

知识点名称 内容
构造函数的
作用

★★★★
1. 对于 C++ 中基本数据类型的变量,可以声明全局变量和函数内部的局部变量。
(1)
全局变量:如果没有进行初始化,则系统自动为其初始化为 0。这个工作在程序启动时完成。
(2)
局部变量:系统不进行自动初始化,如果程序员没有设定,则是一个随机值
2. 
构造函数的作用完成对象的初始化工作(即创建对象)
(1)构造函数是类中的特殊成员函数,它属于类的一部分。
3. 声明对象后,可以使用 
new 运算符为对象进行初始化,此时调用的是对象所属类的构造函数
构造函数的
定义

★★★★★
1. 构造函数的函数名与类名相同,没有返回值。
(1)
一个类的构造函数可以有多个,即构造函数允许重载
(2)即这些构造函数之间的关系是重载关系。
2. 当类中没有定义任何构造函数时,系统会自动添加一个参数表为空、函数体也为空的构造函数,称为
默认构造函数
3. 定义构造函数的形式:

类名::类名(形参 1,形参 2,…,形参 n)
{
    x1=形参 1;
    x2=形参 2; ……
    xn=形参 n;
}
构造函数的
使用

★★★
1. 如果程序中声明了对象数组,即数组的每个元素都是一个对象。
2. 创建
对象时,调用一次构造函数。
3. 对于指针,仅是说明了这个指针,并未与对象相关,所以并
不调用构造函数
4. 如果构造函数的定义中给出了参数的默认值,那么使用构造函数创建对象时,对应的实参是可以省略的。
(1)此时,
使用默认值当作对应实参的值
复制
构造函数

★★★★
1. 复制构造函数是构造函数的一种,也称为拷贝构造函数
(1)它的作用是使用一个已存在的对象去初始化另一个正在创建的对象。
2. 复制构造函数只有一个参数,参数类型是
本类的引用
(1)即引用类自己。
3. 对于类 A 而言,
复制构造函数的原型如下:
(1)格式一:A::A(const A&)
(2)格式二:A::A(A &)
析构函数
★★★★★
1. 与构造函数一样,析构函数也是成员函数的一种,它的名字也与类名相同,但要在类名前面加一个“〜”字符,以区别于构造函数。
2. 
析构函数的特点没有参数,也没有返回值
(1)析构函数不可以多于一个,
不会有重载的析构函数
(2)默认析构函数的函数体为空。
(3)一个类中
有且仅有一个析构函数
3. 
创建对象时自动调用构造函数,在对象消亡时自动调用析构函数
静态变量
★★★★
1. static 用来声明静态变量
2. 
局部变量块内定义的变量,从定义之处开始到本块结束处为止是局部变量的作用域。
3. 
全局变量:指在所有花括号之外声明的变量,其作用域范围是全局可见的,即在整个项目文件内都有效。
类的
静态成员

★★★
1. 类的静态成员有两种:静态成员变量静态成员函数
2. 给静态成员变量
赋初值的格式:类型 类名::静态成员变量=初值;
3. 访问类静态成员格式
(1)类名::静态成员名
(2)对象名.静态成员名
(3)对象指针->静态成员名
4. 
静态成员变量只有一份,被同类所有对象共享
(1)甚至可以在还没有任何对象生成时就访问一个类的静态成员。
常量成员和
常引用成员

1. 使用关键字 const 修饰的量称为常量。
2. 在对象被创建以后,其常量成员变量的值就
不允许被修改,只可以读取其值。
(1)对于常量对象,只能调用常量函数。
(2)总之,常量成员变量的值不能修改,常量对象中的各个属性值均不能修改。
友元
1. 友元使用关键字 friend 标识。
2. 友元的概念破坏了类的封装性和信息隐藏,但有助于数据共享,能够
提高程序执行的效率
友元函数
★★★★★
1. 在友元函数内部可以直接访问本类对象的私有成员
2. 在类定义中,将一个全局函数声明为本类友元函数:
friend 返回值类型 函数名(参数表); 
(1)当有某类 A 的定义后,将类 A 的成员函数说明为本类的友元函数:friend 返回值类型 类 A::类 A 的成员 函数名(参数表);
3. 一个类的成员函数(包括构造函数和析构函数)可以通过使用 friend 说明为另一个类的友元,但友元函数本身并不是类的成员函数,但允许访问类中的所有成员。
友元类
★★★★
1. 在类定义中声明友元类的格式如下:friend class 类名;
2. 友元类的关系是单向的
(1)若说明类 B 是类 A 的友元类,不等于类 A 也是类 B 的友元类。
(2)
友元类的关系不能传递,即若类 B 是类 A 的友元类,而类 C 是类 B 的友元类,不等于类 C 是类 A 的友元类。
3. 友元函数不是类的成员函数,但允许访问类中的所有成员。
(1)在函数体中
访问对象成员时,必须使用对象名.对象成员名”的方式。
(2)在主函数中,调用全局有元函数时,直接写函数名即可。
this 指针
★★★
1. C++ 语言规定,当调用一个成员函数时,系统自动向它传递一个隐含的参数
(1)该参数是一个指向调用该函数的对象的指针
,称为 this 指针,从而使成员函数知道对哪个对象进行操作。
2. 
目的:使用 this 指针,保证了每个对象可以拥有自己的数据成员,但处理这些数据成员的代码可以被所有的对象共享
3. 在
非静态成员函数内部可以直接使用 this 关键字,this 就代表指向该函数所作用的对象的指针。

四、运算符重载 

知识点名称 内容
重载运算符
的概念
★★★★★
1. 可重载的运算符
(1)双目算术运算符 +(加),-(减),*(乘),/(除),%(取模)
(2)关系运算符 ==(等于),!=(不等于),<(小于),>(大于),<=(小于等于),>=(大于等于)
(3)逻辑运算符 ||(逻辑或),&&(逻辑与),!(逻辑非)
(4)单目运算符 +(正),-(负),*(指针),&(取地址)
(5)自增自减运算符 ++(自增),--(自减)
(6)……
2. 
不可重载的运算符
(1)成员访问运算符 .
(2)成员指针访问运算符 .*,->*
(3)域运算符 ::
(4)长度运算符 sizeof
(5)条件运算符 ?:
(6)预处理符号 #
3. 
运算符函数的格式如下
返回值类型 operator 运算符(形参表)
{
    函数体
}

4. 重载运算符的使用
(1)如果定义为全局函数,对于二元运算符,需要为函数传递两个参数
(2)如果定义为
类的成员函数,对于二元运算符,则只需要传递一个参数
重载运算符
的规则
★★★
1. 重载后运算符的含义应该符合原有的用法习惯。
2. 运算符重载不能改变运算符原有的语义,包括运算符的优先级和结合性。
3. 运算符重载不能改变运算符操作数的个数及语法结构。
4. 不能创建新的运算符,即重载运算符不能超出 C++语言允许重载的运算符范围。
5. 重载运算符“()”“[]”“->”或者赋值运算符“=”时,只能将它们重载为成员函数,不能重载为全局函数。
6. 运算符重载不能改变该运算符用于基本数据类型对象的含义。
重载流插入
运算符和流
提取运算符
1. 重载流插入运算符的一般格式如下:
ostream &operator<<(ostream & output, 类名&对象名)
{
    ……
    return output;
}
重载自增、
自减运算符
★★★★
1. 自增运算符“++”有前置后置之分。
(1)例如,obj 是一个类 CDemo 的对象,“
++obj”的返回值应该是 obj 被修改后的值,而“obj++”的返回值应该是 obj 被修改前的值。
2. 使用类运算符“++”运算符,使用函数调用方式。
(1)例:若前缀:
++n 为 n.operator++();
(2)例:若后缀:n++为 n.operator++(0);

五、类的继承与派生 

知识点名称 内容
继承的概念
★★★
1. 使用基类派生新类时,除构造函数和析构函数外,基类的所有成员自动成为派生类的成员,包括基类的成员变量和成员函数。
2. 
派生类可以重新定义或修改基类中已有的成员,包括可以改变基类中成员的访问权限
(1)当然派生类需要定义自己的构造函数和析构函数。
3. 派生类的成员覆盖基类的同名成员。
(1)覆盖也称为
重定义或是重写
(2)对于成员函数来说,派生类既继承了基类的同名成员函数,又在派生类中重写了这个成员函数。
(3)这称为
函数重定义,也称为同名隐藏
派生类
的定义
★★★★★
1. 在 C++ 语言中,从基类派生派生类的一般格式如下:
class 派生类名: 继承方式说明符 基类名
{
    类体
};
继承关系
的特殊性
★★
1. 基类的友元不一定是派生类的友元;基类的成员函数是某类的友元函数,则其作为派生类继承的成员函数仍是某类的友元函数
2. 如果基类的静态成员是公有的或是保护的,则它们被其派生类继承为派生类的静态成员。
(1)访问这些成员时,通常用“
<类名>::<成员名>”的方式引用或调用。
3. 除基类的构造函数和析构函数外,
派生类可以继承基类的全部成员变量和成员函数。
多重继承
★★
1. C++ 中有两种继承:单一继承和多重继承。
(1)对于单一继承,派生类只能有一个基类
(2)对于
多重继承,派生类可以有多个基类,指一个派生类同时有一个以上的基类,多个基类中的所有成员除构造函数和析构函数外都被派生类继承。
访问控制
★★★★

1. 继承方式不同,基类中的成员在派生类中的访问权限可能也不同。
(1)当类的继承方式为公有继承时,基类的公有成员和保护成员的访问属性在派生类中不变,而基类的私有成员在基类外不可直接访问


(2)当类的继承方式为私有继承时,基类中的公有成员以私有成员身份出现在派生类中。

 

(3)保护继承中,基类的公有成员以保护成员的身份出现在派生类中,而基类的私有成员不可以直接访问

 

构造函数与
析构函数
★★★★★
1. 派生类构造函数必须对这三类成员进行初始化,其执行顺序:
(1)调用基类构造函数
(2)
调用子对象的构造函数
(3)
派生类的构造函数体
2. 在执行一个派生类的构造函数之前,总是先执行
基类构造函数
(1)派生类对象消亡时,
先执行派生类的析构函数,再执行基类的析构函数。
类与类之间
的关系
1. 继承关系也称为“is a”关系或“是”关系。
2. 
组合关系也称为“has a”关系或“有”关系,表现为封闭类,即一个类以另一个类的对象作为成员变量。
3. 继承可以是多级的,类 A 可以是类 B 的基类,类 B 可以是类 C 的基类。
(1)可以说类 C 的对象是类 B 中的一员,也是类 A 中的一员。
(2)即
“is a”关系具有传递性
多层次的
派生
1. 在 C++ 中,派生可以是多层次的。
(1)如类 A 派生类 B,类 B 可以再派生类 C,类 C 又能够派生类D,以此类推。
(2)在 C++中,类之间的继承关系具有传递性

六、多态与虚函数 

知识点名称 内容
多态
★★★
1. 多态分为:
(1)编译时多态:静态绑定/早绑定,主要是指函数的重载(包括运算符的重载)。
(2)
运行时多态:动态绑定/晚绑定,和继承、虚函数等概念有关。
2. 不论是静态还是动态,多态性肯定是调用
同名的函数
3. 在类之间满足赋值兼容的前提下,
实现动态绑定必须满足以下两个条件
(1)必须声明
虚函数
(2)通过基类类型的
引用或者指针调用虚函数。
4. 在面向对象的程序设计中,使用多态能够增强程序的可扩充性。
(1)此外,使用多态也能起到精简代码的作用。
虚函数
★★★★
1. 所谓“虚函数”,就是在函数声明时前面加了 virtual 关键字的成员函数。
2. 声明虚函数成员的一般格式:
virtual 函数返回值类型 函数名(形参表);
3. 通过基类指针或基类引用调用虚函数时,都会产生动态多态。
4. 
虚函数的注意事项
(1)虚函数一般不声明为内联函数。
(2)派生类重写基类的虚函数实现多态,要求函数名、参数列表及返回值类型要完全相同。
(3)
基类中定义了虚函数,在派生类中该函数始终保持虚函数的特性
(4)只有类的非静态成员函数才能定义为虚函数,静态成员函数和友元函数不能定义为虚函数。
(5)如果虚函数的定义是在类体外,则只需在声明函数时添加 virtual 关键字,定义时不加 virtual 关键字。
(6)构造函数不能定义为虚函数。
(7)不要在构造函数和析构函数中调用虚函数。
(8)最好将基类的析构函数声明为虚函数。
多态的使用
1. 因为类的成员函数之间是可以互相调用的,所以在普通成员函数(静态成员函数、构造函数和析构函数除外)中调用其他虚成员函数也是允许的,并且是多态的。
2. 在
构造函数析构函数中可以调用虚函数,但这样调用的虚函数不是多态的。
虚析构函数
★★★★
1. C++ 允许声明虚析构函数。
(1)声明虚析构函数的一般格式:virtual 〜类名(); 
(2)虚析构函数没有返回值类型,没有参数。
2. 如果一个类的
析构函数是虚函数,则由它派生的所有子类的析构函数也是虚析构函数
纯虚函数
★★★★★
1. 纯虚函数:声明在基类中的虚函数,没有具体的定义,而由各派生类根据实际需要给出各自的定义。
2. 声明纯虚函数的一般格式:
virtual 函数类型 函数名(参数表)=0;
3. 定义纯虚函数的几个要素是:
(1)使用 virtual 关键字进行修饰;
(2)函数定义中要有“=0”,且没有函数体,大括号也没有。
抽象类
★★★★
1. 包含纯虚函数的类称为抽象类
(1)即抽象类至少含有一个纯虚函数。
2. 抽象类的派生类中,如果没有给出全部纯虚函数的定义,则
派生类继续是抽象类
(1)直到派生类中给出全部纯虚函数定义后,才能实例化一个对象。
(2)虽然不能创建抽象类的对象,但可以
定义抽象类的指针引用
(3)这样的指针和引用可以指向并访问派生类的成员,这种访问具有多态性。
虚基类
1. 定义虚基类的一般格式:
class 派生类名:virtual 派生方式 基类名
{
    派生类体
};

七、输入/输出流 

知识点名称 内容
流类简介
★★
1. C++ 的标准库中有一个面向对象的输入/输出软件包,即 I/O 流类库,输入和输出均是通过流完成的。流是 I/O 流类的核心概念。
(1)输出操作是将一个对象转换成一个字符序列,输出到指定对象。
(2)
输入操作是从某个对象接收到一个字符序列,然后将其转换为相应对象所要求的格式。
2. 常见的头文件有以下 3 个:
(1)
iostream:包含操作所有输入/输出流所需的基本信息
(2)
iomanip:包含格式化 I/O 的带参数流操纵符,可用于指定数据输入/输出的格式。
(3)
fstream:包含处理文件的有关信息,提供建立文件、读/写文件的各种操作接口。
标准流对象
★★
1. C++ 在头文件 iostream 中为用户预定义了 4 个标准流对象,分别是:
(1)cin (标准输入流)
(2)
cout (标准输出流)
(3)
cerr (非缓冲错误输出流)
(4)
clog (缓冲错误输出流)
2. 
重定向,就是改变默认的输入来源,或改变默认的输出目的地。
(1)重定向函数 freopen 的原型:
FILE *freopen( const char *path, const char *mode, FILE *stream);
(2)函数 freopen() 的功能:将 stream 按 mode 指定的模式重定向到路径 path 指向的文件。
如果重定向时发生错误,则关闭原来的 stream,函数返回 NULL。
mode 可以是 "w”(写)或 "r”(读)方式。
流操纵符
★★★★
1. 进制数与前缀
(1)十六进制常量 —— 前缀 0x
(2)十进制常量 —— 无前后缀
(3)八进制常量 —— 前缀 0
(4)长整型常量 —— 后缀 L 或 l
2. 
iostream 中常用流操纵符
(1)endl 输出一个新行符,并清空流
(2)ends 输出字符串结束,并清空流
(3)flush 清空流缓冲区
(4)dec * 以十进制形式输入或输出整数
(5)hex 以十六进制形式输入或输出整数
(6)oct 以八进制形式输入或输出整数
(7)ws 提取空白字符
3. 
常用的用于格式控制的流操纵符
(1)setw()setprecision()setfill()setbase()setiosflagsresetiosflags 等。
(2)在
头文件 iomanip 中还定义了一些用于格式控制的流操纵符。
(3)setbase(int b):设置输出整数时的进制,b 为 8、10 或 16。
(4)setfill(int c):在指定输出宽度的情况下,输出的宽度不足时用 ASCII 码为 c 的字符填充(默认情况是用空格填充)。
(5)setprecision(int n):设置输出浮点数的精度为 n。
(6)setw(int w):指定输出宽度为 w 个字符,或输入字符串时读入 w 个字符,一次有效。
调用 cout 的
成员函数
★★
1. ostream 类提供了在 cout 中控制输出格式的成员函数。常见的用于控制格式的成员函数原型:
(1)设置和返回标志字:
flags()
(2)设置标志位:setf()
(3)清除标志位:unsetf()
(4)设置和返回输出宽度:width()
(5)设置填充字符:fill()
(6)设置数据显示精度:precision()
2. ostream 类还有一些输出流的成员函数,其原型如下:
(1)字符插入:
ostream & put(char c); 
成员函数 put() 的功能是向输出流中插入一个字符 c。
如果给出的参数类型为 int,则
输出该 ASCII 码对应的字符,函数返回输出流对象的引用。
(2)数据块插入:
ostream & write(const char * pch, int nCount);
成员函数 write() 的功能是向输出流中插入 pch 指向的一个长度为 nCount 的字节序列。
调用 cin 的
成员函数
1. istream 类提供了一些公有成员函数,它们可以以不同的方式提取输入流中的数据:
(1)get() 函数:此函数从输入流中读入一个字符(包括空白字符),返回值就是该字符的 ASCII 码。
(2)
getline() 函数:是从输入流中的当前字符开始读取 bufSize-1 个字符到缓冲区 buf,或读到'\n'为止(哪个条件先满足即按哪个执行)。函数会在 buf 中读入数据的结尾自动添加串结束标记'\0'。
(3)
eof() 函数:用于判断输入流是否已经结束。返回值为 true 表示输入结束。
(4)
ignore() 函数:作用是跳过输入流中的 n 个字符。

八、文件操作 

知识点名称 内容
文件的概念
1. C++ 根据文件数据的编码方式不同分为文本文件二进制文件
2. 根据存取方式不同分为
顺序存取文件随机存取文件
3. 对文件的基本操作分为
读文件写文件
(1)所谓“读文件”就是将文件中的数据读入内存之中,也称为“输入”。
(2)所谓“写文件”就是将内存中的数据存入文件之中,也称为“输出”。
C++
文件流类
★★★★
1、C++ 标准类库中有 3 个流类可以用于文件操作,这 3 个类统称为文件流类,分别如下:
(1)ifstream:用于从文件中读取数据。
(2)
ofstream:用于向文件中写入数据。
(3)
fstream:既可用于从文件中读取数据,又可用于向文件中写入数据。
2、使用这 3 个流类时,程序中需要包含 
fstream 头文件
3、使用文件的基本步骤:
打开(open)文件 —— 操作文件 —— 关闭(close)文件。
打开文件
★★★★
1. 打开文件的目的:
(1)建立关联。通过指定文件名,建立起文件和文件流对象的关联。
(2)
指明文件的使用方式和文件格式
2. 打开文件的方式:
(1)先建立流对象,然后调用 open()函数连接外部文件。格式:

流类名 对象名;
对象名.open(文件名,模式);

(2)调用流类带参数的构造函数,在建立流对象的同时连接外部文件。格式如下:
流类名 对象名(文件名,模式);
① 模式
Ⅰ. 
ios::in :以方式打开文件。
Ⅱ. 
ios::out :以方式打开文件。
Ⅲ. 
ios::in | ios::out:既可取其内容,也可向其入数据。
Ⅳ. 
ios::app:以追加方式打开文件,用于在文件尾部添加数据。
② 
文件名
Ⅰ. 可以是已经赋值的字符串,也可以是
字符串常量
Ⅱ. 可以是包含完整路径的
绝对文件名,也可以是只包含相对路径的文件名
Ⅲ. 其中“\\”是 C++ 的转义字符,代表路径中的一个“\”。
Ⅳ. 故打开文件 "d:\file.dat" 的表示方式为:"d:\\file.dat"。
关闭文件
使用 fstream 中的成员函数 close() 关闭文件
读写二进制
文件
1. 用 ostream::write() 成员函数写文件
2. 用 istream::
read() 成员函数读文件
3. 用 ostream::
gcount() 成员函数得到读取字节数
用成员函数
put()和
get()
读写文件
★★
1. 读写文本文件:
(1)成员函数 put() 向文件中一次写入一个字节。
(2)成员函数 
get() 从文件中一次读取一个字节。
2. 
函数 get() 有 3 种主要形式:
(1)
intget(); —— 不带参数的 get()函数从指定的输入流中提取一个字符(包含空白字符),函数的返回值即为该字符。
(2)
istream& get(char &rch); —— 从指定输入流中提取一个字符(包含空白字符),将该字符作为rch 引用的对象。
(3)
istream& get(char *pch, int nCount, char delim='\n'); —— 从流的当前字符 开始 , 读取 nCount-1 个字符,或遇到指定的分隔符 delim 结束。
随机访问
文件
1. 成员函数 seekg(),可以设置文件读指针的位置。
2. 成员函数 seekp(),可以设置文件的写指针位置。

九、函数模板与类模板 

知识点名称 内容
函数模板

概念
★★★★★
1. 定义
(1)函数模板:函数在设计时并不使用实际的类型,而是使用虚拟的类型参数。
① 这样可以不必为每种不同的类型都编写代码段。当用实际的类型来实例化这种函数时,将函数模板与某个具体数据类型连用。
② 即这个通用函数就是函数模板。
(2)
模板函数:编译器将以函数模板为样板,生成一个函数,即产生了模板函数,这个过程称为函数模板实例化。
① 模板函数的真正代码是在源程序中
调用函数时产生。
2. 定义函数模板的一般格式如下:

template <模板参数表>
返回类型名 函数模板名(参数表)
{
    函数体的定义
}

(1)模板参数表:由用逗号分隔的模板参数构成,形式是“类型 参数名,类型 参数名,……”。
① 如果是一个类型,则需要使用
 typename 或 class 关键字来表示参数的类型,一般选用 作为标识符来
标识类型参数。
函数模板

示例
★★
1. 调用函数模板时,不进行实参到形参类型的自动转换
(1)同一个类型参数只能替换为同一种类型。
(2)应保持
参数类型一致
2. 
函数模板与函数的区别
(1)函数模板本身在编译时不会生成任何目标代码,只有当通过模板生成具体的函数实例时才会生成目标代码。
(2)被多个源文件引用的函数模板,应当连同函数体一同放在头文件中,而不能像普通函数那样只将声明放在头文件中。
(3)函数指针也只能指向模板的实例,而不能指向模板本身。
函数或
函数模板
调用语句的
匹配顺序
★★★★★
1. 在函数和函数模板名字相同的情况下,C++ 编译器遵循以下先后顺序:
(1)先找参数完全匹配的普通函数(不是由模板实例化得到的模板函数)。
(2)再找参数完全匹配的
模板函数
(3)然后找实参经过
自动类型转换后能够匹配的普通函数。
(4)如果上面的都找不到,则报错。
类模板
概念
★★★★★
1. 定义
(1)使用类模板,用户可以为类定义一种模式,使得类中的某些成员变量、默认成员函数的参数、某些成员函数的返回值及局部变量能取任意类型,既可以是系统预定义的类型,也可以是用户自定义的类型。
① 通过类模板,可以实例化一个个的类。
(2)由类模板实例化得到的类称为
模板类
(3)关系:编译器由
类模板生成类的过程称为类模板的实例化
① 由类模板实例化得到的类称为
模板类
2. 
类模板声明的格式:template<模板参数表> class 类模板名{ //类体定义};
3. 用类模板定义对象的一般格式:
(1)
类模板名 <模板参数表> 对象名 1,…,对象名 n;
(2)类模板名 <模板参数表> 对象名 1(构造函数实参),…,对象名 n(构造函数实参);
4. 如果要定义二元组的类,则需要根据组成二元组的类型定义很多不同的类。
(1)现在可以使用
类模板来解决问题。
类模板

继承
1. 类之间允许继承,类模板之间也允许继承。
2. 具体来说,类模板和类模板之间、类模板和类之间可以互相继承,它们之间的常见派生关系有以下 4 种情况:
(1)普通类继承模板类
(2)类模板继承普通类
(3)类模板继承类模板
(4)类模板继承模板类

Guess you like

Origin blog.csdn.net/qq_39720249/article/details/131849900