C++ 标准程序库 学习笔记 2012-09-26

1. predicates STL 规定:面对相同的值,predicates 必须返回相同的结果

2. 仿函数, 任何东西,只要行为与函数相似,都可以称为仿函数。(函数行为:可以使用小括号传递参数,籍以调用某个东西)因此,如果定义了一个对象,行为像函数,就可以当作函数来使用,例如:

 1     class PrintInt {
 2         public:
 3             void operator() (int elem) const {
 4                 std::cout << elem << " ";
 5             }
 6     };
 7     
 8     int main ()
 9     {
10         vector<int> coll;
11 
12         //insert elements form 1 to 9
13         for (int i = 1; i <= 9; ++i) {
14             coll.push_back(i);
15         }
16 
17         //print all elements
18         for_each (coll.begin(), coll.end(),
19                 PrintInt());                //operation
20         cout << endl;
21     }

3. 仿函数的优点:

    a. 仿函数是“smart functions" (智能型函数)
        仿函数不同于普通函数,它可以拥有成员函数和成员变量,这也就意味着,它可以拥有状态(state)。事实上,在同一个时间里,由仿函数代表的单一函数里,可能有不同的状态。同时,我们还可以在执行期(runtime)对它们进行初始化。

    b. 每个仿函数都有自己的型别
        一般函数只有标记式不同的时候,才算型别不同。而仿函数即使标记式相同,也可以拥有不同的型别。由于每一个仿函数均有一个自己的型别, 因此我们可以将函数行为当作 template 参数来运用。这使得不同型别的容器可以使用相同类别的仿函数做为排序准则。确保不会在排序准则不同的群集(collection)之间赋值、合并或比较。我们甚至可以设计仿函数继承体系,以此完成某些特别的事情。

    c. 仿函数通常比一般函数速度快
        就 template 概念而言,由于更多细节在编译期间就已经确定,所以通常可能进行更好的最佳化,所以,传入一个仿函数,可能获得更好的性能。

4. vector 模拟出了一个动态数组,本身是一个“将元素置于动态数组中加以管理”的一个抽象概念。它本身支持随机存取,但是增删元素时,在末端性能较好。

5. 对于 vector 而言,它配置了比实际容量更多的内存,它的容量很重要:一旦需要重新配置内存,和 vector 相关的所有 references、pointers、iterators都会失效。重新配置内存很耗时间。

6. 对于 vector 容器,可以通过 reserve 进行重新分配内存,来增加容量,但是不能通过它减少容量, std::vector<T>(v).swap(v) 可以完成减少容量的工作。

7. 对于 vector 中,c.at (idx)、c[idx]、c.front()、c.back()中,只有 c.at (idx) 进行了范围检查,当越界时会抛出 out_of_range 异常,其它操作均未进行检查。因此,再使用的时候,需要确保索引有效。

8. vector 保证了 vector 所有元素分布于连续的空间中,因此 保证了对于vector内的任意合法索引,以下表达式一定为true:

  &v[i] = &v[0] + i;

    因此,不管出于什么原因,只要需要一个元素类型为 T 的数组,就可以采用 vector<T>,然后传递第一个元素的地址给它,如下所示:

1     std::vector<char> v;
2 
3     v.resize(41);
4     strcpy(&v[0], "hello, world");
5     printf("%s\n", &v[0]);

9. vector 中的 vector<bool> 属特化版本。

10. deques 是一个与 vector 相似的,头尾两端都开放,可以进行快速安插和删除操作的容器。


11. 与 vector 相比, deques 功能上的不同之处在于:

    a. 两端都能进行快速安插和移除元素(vector 只能在尾部进行)。并且可以在分期摊还的常数时间内完成。

    b. 存取元素时,deque 内部会多一个间接过程,所以元素的存取和迭代器的动作会稍微慢一些。

    c. 迭代器需要在不同的区块间跳转,所以必须是特殊的智能指针,非一般指针。

    d. 在对内存区块有限制的系统中(如PC系统),deque 可以内含更多元素,因为它使用不止一块内存。因此 deque 的 max_size() 会更大。

    e. deque 不支持对容量和内存重分配时机的控制。特别的是,除了头尾两端,在任何地方进行插入和删除元素操作,都会使得所有指向 deque 元素的 pointers、references、iterators失效。不过,deque 的内存重分配优于 vector ,因为内部结构显示,deque 不必在内存重分配时复制所有元素。

    f. deque 的内存块不被使用时,会被释放。deque 的内存大小是可以缩减的。不过,具体做法,由不同的版本定义。

12. 如下情形,最好采用 deque :

    a. 需要在两端进行安插和移除元素。

    b. 无需引用容器内的元素。

    c. 要求容器释放不再使用的元素。

13. deque 不提供容量操作(capacity() 和 reserve() )。

14. deque 的元素的插入和移除都可能导致内存的重新分配,所以任何插入或删除的动作都会使所有指向 deques 元素的 pointers、references 和 iterators 失效。唯一例外的是在头部或尾部插入元素,动作之后,pointers 和 references 仍然有效(但 iterators 就没这么幸运了)。

posted @ 2012-09-26 18:18  愤怒的豆沙包  阅读(408)  评论(0编辑  收藏  举报