STL
C++ STL提供了vector,string,list等容器,其中vector封装数组,list封装链表,map和set封装二叉树等。STL以成员函数方式提供常用操作,如插入、删除、排序、查找等。
vector, list
二者不同于数组的一点是,支持动态增长。不同在于:
- vector是顺序表,表示一块连续的内存;list是双向链表,在内存中不一定连续。
- 当内存不够时,vector会重新申请一块新内存,对数据做拷贝。list不用考虑内存的连续。
- list通过指针访问元素,随机访问的效率低。需要随机存取元素时,vector更合适。
- 向vector插入或删除一个元素时,会复制移动待插入元素右边的所有元素。有频繁插入删除操作时,list更合适。
map,set
set和map内部采用平衡检索二叉树:
关联容器的插入删除效率比其他容器高?所有元素以节点方式存储,插入和删除时,不需要做内存拷贝和内存移动,只是指针的方向变动。
每次insert后,以前保存的iterator不会失效?iterator相当于指向节点的指针,内存没有变,指向内存的指针就不会失效。相对于vector来说,每次删除和插入,指针都有可能失效。原因是,为了保证内存数据的连续存放,当容器内部空间不够时,会开辟一块新的更大的内存,释放之前的内存,复制已有的数据到新的内存。
extern
可置于变量或函数前,原理是告诉编译器:“你现在编译的文件中,有一个标识符虽然没有在本文件或本文件当前位置中定义,但是它是在别的文件中或本文件其它位置定义的全局变量,你要放行!”
const
作用 | 说明 | 代码 | |
---|---|---|---|
1 | 定义const常量 | const int Max = 100; | |
2 | 类型检查 | const有数据类型,而宏常量没有。编译器可以对前者进行类型安全检查,避免后者在字符替换时产生意想不到的错误 | void f(const int i){…..}//不匹配时提示 |
3 | 保护被修饰的对象 | 防止意外修改,增强程序健壮性 | void f(const int i){i=10;//error!}//如果在函数体内修改i,编译器会报错 |
4 | 方便地进行参数的调整和修改 | 同宏定义一样,做到一变都变 | |
5 | 为函数重载提供一个参考 | class A {… void f(int i) {…} void f(int i) const {….} } |
|
6 | 节省空间,避免不必要的内存分配 | const定义常量从汇编的角度来看, 只是给出了对应的内存地址, 而不是象#define一样给出的是立即数, 所以,const定义的常量在程序运行过程中只有一份拷贝, 而#define定义的常量在内存中有若干个拷贝 |
#define PI 3.14159 //常量宏 const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 …… double i=Pi; //此时为Pi分配内存,以后不再分配! double I=PI; //编译期间进行宏替换,分配内存 double j=Pi; //没有内存分配 double J=PI; //再进行宏替换,又一次分配内存! |
7 | 提高效率 | 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高 |
虚函数
实现了多态机制,用父亲类别的指针指向其子类的实例,然后通过父亲的指针调用实际子类的成员函数。
虚函数是通过一张虚函数表(virtual table)实现的。它像一张地图,指明了实际所应调用的函数。