3. C++
3.1 概览
函数指针、位运算、引用、const、动态内存分配、内联函数、重载函数、函数缺省参数、面向对象、复制构造函数、类型转换构造函数、析构函数、静态成员变量、成员对象、封闭类、友元、this指针、常量对象、常量成员函数、常引用、运算符重载(赋值运算符重载)、运算符重载为友元函数、可变长数组、流插入运算符和流提取运算符的重载、自增自减运算符重载、派生和继承、复合关系和继承关系、基类派生类同名成员与protected、派生类的构造函数、Public继承的赋值兼容性规则、多态和虚函数、多态的实现原理、虚析构函数、纯虚函数和抽象类、文件操作、函数模板、类模板、string类、输入输出、流操纵算子、标准模板库、vector、list和deque、Set和multiset、map和multimap、Adapters…
3.2 函数指针
程序运行时,函数占据一片连续的内存空间,函数名表示这片空间的起始地址,可以将该地址赋给一个指针变量,使变量指向该函数,然后可通过指针变量调用函数。该指针变量称为函数指针
如何定义?
类型名 (* 指针变量名)(参数类型1, 参数类型2,…);
用法?
函数名赋给函数指针,调用方法:函数指针名(实参表);
实例?
C语言提供了快排库函数:void qsort(void *base, int nelem, unsigned int width,int(* pfCompare)( const void *, const void *));参数分别表示:数组起始地址、数组元素个数、每个元素大小、排序规则(比较函数的地址)。最后一个参数便是函数指针类型。
比较函数的写法:int 函数名(const void * elem1, const void * elem2);略
p.s. main函数的参数为:int argc, char * argv[]
argc: 代表启动程序时,命令行参数的个数。C/C++语言规定,可执行程序程序本身的文件名,也算一个命令行参数,因此,argc的值至少是1
argv: 指针数组,其中的每个元素都是一个char* 类型的指针,该指针指向一个字符串,这个字符串里就存放着命令行参数
3.3 位运算
略
例1. 有两个int型的变量a和n(0 <= n <= 31),要求写一个表达式,使该表达式的值和a的第n位相同
(a >> n) & 1 或 (a & (1 << n)) >> n
3.4 引用
如何定义一个引用?
类型名 & 引用名 = 变量名;
引用和原变量有何关系,如何理解?
等价。引用相当于是原变量的别名。
引用的注意事项?
定义引用时必须初始化,且引用后不可再引用其他变量
常引用?
添加const关键字,不能通过常引用去修改其引用的内容
常引用与非常引用转换?
略
3.5 const
作用?
定义常量、常量指针、常引用
常量指针?
不可通过常量指针修改其指向的内容,不能把常量指针赋值给非常量指针,反过来可以。常量指针的意义:?函数参数为常量指针时,可避免函数内部不小心改变参数指针所指地方的内容
3.6 动态内存分配
如何实现动态内存分配?
P = mew T;P是类型为T*的指针,动态分配出一片大小为 sizeof(T)字节的内存空间,并且将该内存空间的起始地址赋值给P
如何动态分配数组?
P = new T[N];类型为T*的指针。动态分配出一片大小为 sizeof(T)字节的内存空间,并且将该内存空间的起始地址赋值给P
如何释放动态分配的内存?
delete指针,对于数组,要加[]
3.7 内联函数
内联函数机制如何?
inline关键字,插入函数代码,而非调用
3.8 函数重载
何为函数重载?
函数名同,参数个数或参数类型不同
3.9 函数的缺省参数
如何定义缺省参数?
定义函数的参数列表最右边的连续若干个参数有缺省值
3.10 面向对象
类如何定义?
class关键字,最后记得加;
对象的内存分配如何?
对象的大小 = 所有成员变量的大小之和
对象支持哪些运算?
可以用=赋值,不能进行比较,除非重载
如何访问类的成员变量和成员函数?
对象名.成员名
指针->成员名
引用名.成员名
类的成员函数有哪些写法
函数体和定义分开写,需要用::符
3.11 构造函数
何为构造函数?
名字与类名相同,可以有参数,不能有返回值,其作用是对对象进行初始化,没有写构造函数的话,编译器会生成一个默认的无参构造函数,否则不会生成
构造函数何时调用?
对象生成时自动调用,生成后不会再调用
构造函数如何修饰?
public,private构造函数不能直接用来初始化对象
3.12 类成员的可访问范围
类成员的可访问范围有哪些关键字?
- private: 指定私有成员, 只能在成员函数内被访问
- public: 指定公有成员, 可以在任何地方被访问
- protected: 指定保护成员
缺省是哪种修饰符?
private
设置私有成员的目的?
强制对成员变量的访问一定要通过成员函数进行
3.13 复制构造函数
何为复制构造函数?
唯一参数,为同类对象的引用,形如X::X(X&)或X::X(const X&),如果没有定义复制构造函数,那么编译器生成默认复制构造函数。默认的复制构造函数完成复制功能。如果定义了自己的复制构造函数,则默认的复制构造函数不存在
复制构造函数起作用何时起作用?
1)当用一个对象去初始化同类的另一个对象时
2)如果某函数有一个参数是类 A 的对象,那么该函数被调用时,类A的复制构造函数将被调用
3)如果函数的返回值是类A的对象时,则函数返回时,A的复制构造函数被调用
3.14 类型转换构造函数
类型转换构造函数的目的是什么?
实现类型的自动转换
何为实现类型的自动转换?
只有一个参数,且不是复制构造函数
p.s.类型不匹配时,会建立一个临时对象/临时变量
3.15 析构函数
何为析构函数?
名字与类名相同,前面加~,没有参数和返回值,一个类最多有一个析构函数
析构函数机制是怎样的?
对象消亡时,自动被调用,以处理善后工作,如释放分配的空间等
缺省?
定义类时没写析构函数, 则编译器生成缺省析构函数,不涉及释放用户申请的内存释放等清理工作。定义了析构函数, 则编译器不生成缺省析构函数
析构函数与数组关系?
对象数组生命期结束时,对象数组的每个元素的析构函数都会被调用
析构函数与delete?
delete运算导致析构函数调用
3.16 静态成员
何为静态成员?
static修饰
静态成员特性?
普通成员变量每个对象有各自的一份,而静态成员变量一共就一份,为所有对象共享
普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用与某个对象
因此静态成员不需要通过对象就能访问
p.s.sizeof不会计算静态成员变量
如何访问静态成员?
类名::成员名
对象名.成员名
指针->成员名
引用.成员名
限制?
在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数
3.17 成员对象和封闭类
何为成员对象?何为封闭类?
一个类的成员变量是另一个类的对象。包含成员对象的类为封闭类
封闭类如何初始化?
定义构造函数时,添加初始化列表
类名::构造函数(参数表):成员变量1(参数表),成员变量2(参数表),… { }
调用顺序?
当封闭类对象生成时:先执行所有成员对象的构造函数,再执行封闭类的构造函数
成员对象的构造函数调用顺序和成员对象再类中的说明顺序一致,与在成员初始化列表中出现的顺序无关