1. vector中元素的访问:[]与at操作
2. 调整vector的大小:reserve
reserve是保证vector的容量至少为某个值,它不会减少vector的容量。
resize是改变vector的大小,这个操作比较严格,给出多少,结果vector的容量就变为多少。
3. sprint的替代方案
4. 定位new表达式
5. 模板特化与函数重载
类模板可以被偏特化或者全特化,函数模板则只能够被全特化
重载决议只决定选出主模板
分析下面的代码:
程序运行结果是:f<int>(int*)
即调用的是第3个函数。
这儿容易让人疑惑的是,为什么不是第4个函数:template<>void f<int*>(int*) 呢?这个是template <class T>void f(T)的模板特化啊。
要理解这个就需要注意一点:带有函数模板的重载进行决议的时候,选择的规则是首先选择最优的普通函数,如果没有适合的普通函数那么就要从模板函数中选择。而进行选择的时候,是决定选择的哪个主模板函数,然后再看这个主模板函数是否存在对应的特化。所以,对于上面的选择,首先是在
template <class T>
void f(T)
和
template <class T>
void f(T*)
之间进行选择,发现第2个更加合适,这样就确定了主模板函数,然后在查找该主模板函数是否有对应的特化函数,这样正好找到了
template<>
void f<int>(int*)
它是对int的特化,所以最后选择了这个函数。
分开看是如下:
和
6. 异常使用的正确位置
资源获取即初始化RAII
尽量通过析构函数来进行异常环境下的自动清理工作,而不是通过try/catch块
永远不要允许析构函数、释放操作(deallocation)以及swap()函数抛出任何异常,因为否则的话,就没法安全且可靠地进行资源的清理了。
7. 违反异常规格
C++中的一些比较不起眼的特性,逐渐被尘封在语言的角落,直到许多人甚至于忘记了它们的存在。这正是为什么你看到的关于它们的文章总是相对较少,譬如像valarray、bitset、locale以及实际上是合法的表达式"5[a]"这些冷僻的特性。而对于异常规格来说同样如此。
如果函数违反了异常规格的话,该函数肯定不能够以通常的函数返回方式返回,而它做的事情有如下两件:
8. 类继承中构造顺序
验证程序如下:
9. 访问权限的使用
10. 类中隐式声明的函数
11. C++中不同层次的内存分配情况
12. new或malloc实际分配空间的大小
如果想到内存对齐的情况,这个问题就很好解决了。
内存对齐的情况要求实际得到的内存肯定不会小于要求分配的。一般都是高于这个值。
13. STL中各容器额外的内存开销
14. C++中new三种形式
15. 类相关的new:与全局new是不同的
简单new:plain new的重载
定位new:placement new的重载
nothrow new的重载
16. 初始化陷阱
注意在初始化的时候,不要搞成函数声明
17. C++操作符上的贪婪匹配
18. C++中的union
19. 单片式设计陷阱