1.多态 : 一个switch, 一个函数指针 重载,覆盖,隐藏
const 引用必须在初始化列表中初始化
纯虚函数 virtual void eat()=0
VTABLE虚函数初始化表
C++ 不允许隐式转换
2。多态分为四类 : 参数多态,包含多态, 强制多态,重载多态
3.虚函数提供了一中更为灵活的动态性机制。虚函数允许函数调用与函数体之间的联系在运行是建立(动态联编)
4.对虚函数的定义的几点说明 :
(1)通过定义虚函数使用C++提供的多态性机制时,派生类应从其基类公有派生
(2)必须首先在基类定义为虚函数
(3)C++规定,当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数。
(4)一般是先定义基类指针,然后通过基类指针指向派生类,访问虚函数获取运行时多态性
(5)虚函数必须是类的成员函数,不能是友元函数,也不能是静态成员函数
(6)内联函数不能是虚函数,因为内联函数是在编译地确定位置,虚函数虽然定义在类内部,但编译时仍将其视为非内联
(7)构造函数不能是虚函数。因为虚函数作为运行过程中多态的基础,主要是针对对象的,而构造函数是在对象产生之前运行的,因此虚构造函数无意义。
(8)析构函数可以是虚函数
5.编译时的多态 : 函数重载
运行时的多态 : 虚函数和继承
6.静态联编 :
动态联编:
7.纯虚函数定义 :是一个基类中说明的虚函数,它在该基类中没有定义,但要求在它的派生类中必须定义自己的版本,或重新说明为纯虚函数
8.纯虚函数的特点:
(1)没有函数体
(2)最后面“=0”并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”
(3)这是一个声明语句,最后应有分号。
9.抽象类 :不用来定义对象而只作为一种基本类型用作继承的类,由于它常用作基类,通常称为抽象基类
抽象类的特点 :
(1)凡是包含纯虚函数的类都是抽象类(至少一个纯虚函数)
(2)抽象类只能作为其他类来使用,不能建立抽象类对象。因为纯虚函数是不能被调用的,包含纯虚函数的类是无法建立对象的,其纯虚函数的实现由派生类给出
10. 重载,覆盖,隐藏
成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual关键字可有可无。
覆盖 : 派生类函数覆盖基类函数 特征:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual关键字
隐藏 : 派生类函数屏蔽了与其同名的基类
11.C++核心优势之一便于软件的重用
12.C++中有两个方面体现重用 :
1. 面向对象的思想 :继承,多态,标准类库
2.泛型程序设计(generic programming)的思想 :模版机制,以及标准模版库STL
13 泛型程序设计
将一些常用的数据结构 (比如链表,数组,二叉树)和算法(比如排序,查找)写成模版,以后则不论数据结构里放的是什么对象,算法针对什么样的对象,则都不必重新实现数据结构,重新编写算法
标准模版库(Standard Template Library): 一些常用数据结构和算法的模版的集合。由Alex Stepanov开发,于1998年被添加进C++ 标准
13. 模版分类
函数模版(function template)
是独立于类型的函数
可产生函数的特定版本
类模版(class template)
跟类相关的模版, 如vector
可产生类对特定类型的版本, 如vector <int>
14.模版的工作方式 : 函数模版只是说明, 不能直接执行,需要实例化为模版函数后才能执行
15. 模版优缺点 :
优点:函数模版方法克服了C语言解决上述问题时用大量不同函数名表示相似功能的坏习惯
克服了宏定义不能进行参数类型检查的弊端
克服了C++函数重载用相同函数名字重写几个函数的繁琐
缺点 :调试比较困难
16.容器 :可容纳各种数据类型的数据结构
迭代器 :可依次存取容器中元素的东西
算法 :用来操作容器中的元素的函数模版,例如, STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象
17.函数本身与他们操作的数据的结构和类型无关。
18.容器概述 :
1)可以用于存放各种类型的数据(基本类型的变量,对象等)的数据结构
2)容器分为三大类:
1) 顺序容器
vector : 后不插入/删除,直接访问
deque : 前/后部插入/删除,直接访问
list : 双向链表,任意位置插入/删除
2) 关联容器
set : 快速查找,无重复元素
multiset : 快速查找,可有重复元素
map : 一对一映射,无重复元素,基于关键字查找
multimap :一对一映射,可有重复元素,基于关键字查找
前两者和称为第一类容器
3)容器适配器
stack : LIFO
queue : FIFO
priority_queue : 优先级高的元素先出
3)对象被插入容器中时,被插入的是对象的一个复制品
许多算法, 比如排序,查找,要求对容器中的元素进行比较,所以,放入容器的对象所属的类,还应该实现 == 和 < 运算符
19.顺序容器简介
1) vector 头文件 <vector>
实际上就是个动态数组。随机存取任何元素都能在常数时间完成。在尾端增删元素具有较佳的性能。
2) deque 头文件 <deque>
也是个动态数组,随机存取任何元素都能在常数时间完成(但性能次于vector)。在两端增删元素具有较佳的性能。
3) list 头文件 <list>
双向链表,在任何位置增删元素都能在常数时间完成。不支持随机存取。
上述三种容器称为顺序容器,是因为元素的插入位置同元素的值无关。
20.关联容器简介
关联式容器内的元素是排序的,插入任何元素,都按相应的排序准则来确定其位置。关联式容器的特点是在查找时具有非常好的性能。
1) set/multiset: 头文件 <set>
set 即集合。set中不允许相同元素,multiset中允许存在相同的元素。
2) map/multimap: 头文件 <map>
map与set的不同在于map中存放的是成对的key/value。并根据key对元素进行排序,可快速地根据key来检索元素map同multimap的不同在于是否允许多个元素有相同的key值。
上述4种容器通常以平衡二叉树方式实现,插入和检索的时间都是 O(logN)
21.容器适配器简介
1) stack :头文件 <stack>
栈。是项的有限序列,并满足序列中被删除、检索和修改的项只能是最近插入序列的项。即按照后进先出的原则
2) queue :头文件 <queue>
队列。插入只可以在尾部进行,删除、检索和修改只允许从头部进行。按照先进先出的原则。
3)priority_queue :头文件 <queue>
优先级队列。最高优先级元素总是第一个出列
22.容器的共有成员函数
1) 所有标准库容器共有的成员函数:
相当于按词典顺序比较两个容器大小的运算符:
=, < , <= , > , >=, == , !=
empty : 判断容器中是否有元素
max_size: 容器中最多能装多少元素
size: 容器中元素个数
swap: 交换两个容器的内容
2) 只在第一类容器中的函数:
begin 返回指向容器中第一个元素的迭代器
end 返回指向容器中最后一个元素后面的位置的迭代器
rbegin 返回指向容器中最后一个元素的迭代器
rend 返回指向容器中第一个元素前面的位置的迭代器
erase 从容器中删除一个或几个元素
clear 从容器中删除所有元素
head Tail
rend begin rbegin end
23.迭代器
1).用于指向第一类容器中的元素。有const 和非 const两种。
2).通过迭代器可以读取它指向的元素,通过非const迭代器还能修改其指向的元素。迭代器用法和指针类似。
3).定义一个容器类的迭代器的方法可以是:
容器类名::iterator 变量名;
或:
容器类名::const_iterator 变量名;
4).访问一个迭代器指向的元素:
* 迭代器变量名
5).迭代器可以执行++操作,以指向容器中的下一个元素,如果迭代器到达了容器中的最后一个元素的后面,则迭代器变成past-the-end值
注意:使用一个past-the-end值的迭代器来访问对象是非法的
6).STL中的迭代器
STL 中的迭代器按功能由弱到强分为5种:
1. 输入:Input iterators 提供对数据的只读访问。
2. 输出:Output iterators 提供对数据的只写访问
3. 正向:Forward iterators 提供读写操作,并能一次一个地向前推进迭代器。
4. 双向:Bidirectional iterators提供读写操作,并能一次一个地向前和向后移动。
5. 随机访问:Random access iterators提供读写操作,并能在数据中随机移动。
编号大的迭代器拥有编号小的迭代器的所有功能,能当作编号小的迭代器使用
7)不同迭代器所能进行的操作(功能)
所有迭代器: ++p, p ++
输入迭代器: * p, p = p1, p == p1 , p!= p1
输出迭代器: * p, p = p1
正向迭代器: 上面全部
双向迭代器: 上面全部,--p, p --,
随机访问迭代器: 上面全部,以及:
p+= i, p -= i,
p + i: 返回指向 p 后面的第i个元素的迭代器
p - i: 返回指向 p 前面的第i个元素的迭代器
p[i]: p 后面的第i个元素的引用
p < p1, p <= p1, p > p1, p>= p1
8)容器所支持的迭代器类别
容器 迭代器类别
vector 随机
deque 随机
list 双向
set/multiset 双向
map/multimap 双向
stack 不支持迭代器
queue 不支持迭代器
priority_queue 不支持迭代器
24.算法简介
1)STL中提供能在各种容器中通用的算法,比如插入,删除,查找,排序等。大约有70种标准算法。
算法就是一个个函数模板。
算法通过迭代器来操纵容器中的元素。许多算法需要两个参数,一个是起始元素的迭代器,一个是终止元素的后面一个元素的迭代器。比如,排序和查找
有的算法返回一个迭代器。比如 find() 算法,在容器中查找一个元素,并返回一个指向该元素的迭代器。
算法可以处理容器,也可以处理C语言的数组
2)算法分类
变化序列算法
copy ,remove,fill,replace,random_shuffle,swap, …..
会改变容器
非变化序列算法:
adjacent-find, equal, mismatch,find ,count, search, count_if, for_each, search_n
以上函数模板都在<algorithm> 中定义
此外还有其他算法,比如<numeric>中的算法
3)find()
template<class InIt, class T>
InIt find(InIt first, InIt last, const T& val);
first 和 last 这两个参数都是容器的迭代器,它们给出了容器中的查找区间起点和终点。
这个区间是个左闭右开的区间,即区间的起点是位于查找范围之中的,而终点不是
val参数是要查找的元素的值
函数返回值是一个迭代器。如果找到,则该迭代器指向被找到的元素。如果找不到,则该迭代器指向查找区间终点。
4).顺序容器
除前述共同操作外,顺序容器还有以下共同操作:
front() :返回容器中第一个元素的引用
back() : 返回容器中最后一个元素的引用
push_back(): 在容器末尾增加新元素
pop_back(): 删除容器末尾的元素
比如,查 list::front 的help,得到的定义是:
reference front();
const_reference front() const;
list有两个front函数
5)算法解释
ostream_iterator<int> output(cout ,“*");
定义了一个 ostream_iterator 对象,可以通过cout输出以 * 分隔的一个个整数
copy (v.begin(),v.end(),output);
导致v的内容在 cout上输出
copy 函数模板(算法):
template<class InIt, class OutIt>
OutIt copy(InIt first, InIt last, OutIt x);
本函数对每个在区间[0, last - first)中的N执行一次 *(x+N) = * ( first + N) ,返回 x + N
对于copy (v.begin(),v.end(),output);
first 和 last 的类型是 vector<int>::const_iterator
output 的类型是 ostream_iterator<int>
25.list容器
在任何位置插入删除都是常数时间, 不支持随机存取,除了具有所有顺序容器都有的成员函数外,还支持8个成员函数 :
push_front : 在前面插入
pop_front : 删除前面的元素
sort :排序(list 不支持STL的算法sort)
remove : 删除和指定值相等的所有元素
unique : 删除所有和前一个元素相同的元素
merge : 合并两个链表,并清空被合并的那个
reverse : 颠倒链表
splice : 在指定位置前面插入另一链表中的一个或多个元素,并在另一链表中删除被插入的元素
26. sort
sort 实际上是快速排序,时间复杂度 O(n*log(n));
平均性能最优。但是最坏的情况下,性能可能非常差。
如果要保证“最坏情况下”的性能,那么可以使用stable_sort
stable_sort
stable_sort 实际上是归并排序(将两个已经排序的序列合并成一个序列),特点是能保持相等元素之间的先后次序
在有足够存储空间的情况下,复杂度为 n * log(n),否则复杂度为 n * log(n) * log(n)
stable_sort 用法和 sort相同
排序算法要求随机存取迭代器的支持,所以list 不能使用排序算法,要使用list::sort
partial_sort : 部分排序,直到 前 n 个元素就位即可
nth_element : 排序,直到第 n个元素就位,并保证比第n个元素小的元素都在第 n 个元素之前即可
partition: 改变元素次序,使符合某准则的元素放在前面