• 阅读笔记《C++标准程序库》


     《C++标准程序库》

             ——————2013/1

     

    第五章 

    5.1 STL Components   STL的基本观念是将数据和操作分离(与OOP观念相矛盾),数据由容器container管理,操作由算法algorithm定义,迭代器iterator充当粘合剂。

     

    5.2 Containers   序列容器Sequence containers(可序ordered):vectordequelist

         关联容器Associative containers(已序sorted):setmultisetmapmultimap

       容器适配器Container adaptersstackqueuepriority_queue

     

    5.3 Iterator   任何容器都定义了两种迭代器型别:

    Container::iterator /写     Container::const_iterator 只读

    双向迭代器(递增++、递减--):listsetmultisetmapmultimap

    随即存取迭代器(++--+-):vectordequestring

     

    5.4 Algorithm   区间采用半开半闭,当begin() == end()容器为空

     

    5.5 Iterator Adapter   三种迭代器适配器:

    1.  Insert iteratorback_inserter(container)/front_inserter(container)/inserter(container,pos)运用copy函数,目标容器空间不足可用:copy(coll1.begin(), coll1.end(), front_inserter(coll2));只要容器coll2提供有push_front()则能正常运行。

        2.  Stream iteratoristream_iteratorostream_iterator

    从标准输入读入容器:

    copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(coll1));

    从容器输出到标准输出:

    copy(coll1.begin(), coll1.end(), ostream_iterator<int>(cout,  ”  ”));

    3.  Reverse iteratorrbegin(), rend()

     

    5.6 Manipulating/Modifying Algorithm   

           (为使算法达成最大弹性,容器和数组均适用)任何“以迭代器访问容器元素”的算法,都不得(无法)透过迭代器调用容器类别所提供的任何成员函数(数组本身没有成员函数),即不必了解容器细节。  例:remove()算法删除一个容器的末尾元素,会返回一个新的指向结尾的迭代器,但是容器本身的end()却未改变,需要程序员去完成。

    为此,(成员函数vs算法),应永远优先选择成员函数。

     

    5.7 User-Defined Generic Functions

     

    5.8 以函数作为算法的参数

    1. void Print(int value);

       for_each(col1.begin(), col2.end(), Print());

       作用:该容器内,每个元素均调用一次Print().

    2. 一元判断式:指定函数仅一个参数,返回bool类型

    3. 二元判断式:指定函数有两个参数,返回bool类型

     

    5.9 Function Object

    一个类class Fun,让它重载operator(), 那么该类对象就有了函数特性,即为函数对象。

     

    5.10 容器内的函数

    1. 容器元素应满足的条件。

    2. STL只支持value语义,不支持reference,这样利弊参半。只能用指针代替,但是存在一般指针的常见问题,例如比较时,比较的事指针的值,而不是指针所指的值。

     

    5.11 STL内部的错误处理和异常处理

    1. 为提高效率,STL的错误检查几乎没有。所以违反规则就会导致未定义行为。

    迭代器,区间,覆盖等操作很易出错。

    2. C++异常处理的一些基本保证:P139140

     

    第六章 STL Container

    6.1 容器的共通能力和共通操作

    1. 容器的元素都是value,而非reference;元素形成一个序列,即可以一次或多次遍历每个元素;传参时必须符合要求,否则引起未定义行为。

    2. 容器类别的共通操作函数:P145

    3. vector<int> c(istream_iterator<int>(cin), istream_iterator<int>()); 可能被当做一个函数。所以要写成 vector<int> c( ( ), ( ) );

    4. 成员函数 empty() 等价于 size()==0;但前者效率更佳。

    5. 赋值操作是将源容器的所有元素拷贝到目标容器,原目标容器的所有元素被删除,所以代价高昂。若源容器不再使用可采用swap()交换,它只交换内部指针,所以时间复杂度为常数。

     

    6.2 Vector namespace std{

    template <class T,  class Allocator=allocator<T> >

    class vector;}

    1. size()当前元素个数, max_size()最大可分配的容量, capacity()动态数组当前容量, reserve()预留容量(为提高效率)

    2. vector的操作函数P150151152154

    3. vector<bool>特例。 动态位存储,节省空间

     

    6.3 Deque namespace std{

    template <class T,  class Allocator=allocator<T> >  

    class deque; }

    1. 采用动态数组,但是和vector不一样的是 deque采用多个区块,所以内存重分配时优于vector,因为无需复制所有元素。

    2. 由于第一点,所以元素的存取和迭代器的动作稍慢,需要在不同的区块间跳转,需要特殊的智能指针。

    3. deque不提供容量操作capacityreserve;但是多了在头插入删除push_frontpop_front,其它的基本和vector一样。

     

    6.4 List namespace std{

    template <class T,  class Allocator=allocator<T> >

    class list;}

    1. list采用双向链表,不提供随机存取,只有back()front()能直接存取,所以不提供下标操作[]at();但在任何位置安插删除元素都非常快。

    2. 提供多种成员函数P169-171

    3. STLlist对异常安全性提供了最佳支持。

     

    6.5 Set 和 Multiset

    namespace std{

      template <class T, class Compare=less<T>, class Allocator=allocator<T> >

      class set/multiset;}

    1. 排序准则默认为函数对象less<T>,可用两种方法传入排序准则:

    (1)template参数定义:std::set<int, std::greater<int> > col1;

    (2)以构造函数定义:set<Elem, Op>   详见P177.

    2. 元素必须的排序准则:反对称(x<y,y<x);可传递;非自反(x<x永为假)

    3. 只有元素类型,比较准则都相同容器才能比较,否则发生编译错误。

    4. 数据结构采用:红黑树(是二叉平衡树的一种,二叉平衡树是二叉排序树的一种)

    5. 因为插入元素时就自动排序,所以容器内的元素不能改变其值,而双向迭代器指向的元素都被视为常数;若要改变元素值,只能删除旧的,插入新的。

    6. 多次插入删除时,一次处理完比逐一调用快得多。插入函数有一个位置参数作为插入提示,可大大加快速度。

     

    6.6 Map 和 Multimap

    namespace std{

    Template< class Key,  class T,  class Compare = less<key>, 

     class Allocator = allocator<pair<const Key, T> > >

    class map/multimap;}

    1. map拥有set的所有能力和操作函数。set是特殊的mapkeyvalue相等。

    2. map提供下标操作符,可直接存取元素,multimap没有。若指定下标key不存在,则自动创建,而value采用该类型的默认构造函数。

    3. 所有元素的key被视为常数。若要修改key,而不改变value,可采用一个比较方便的方法:map1[“new_key”]=map1[“old_key”]; map1.erase(“old_key”);

    4. 实例:关联式数组p207、字典p209

    5. 综合实例:如何撰写使用function object;如何在执行期定义排序准则;如何在“不在乎大小写”的情况下比较字符串(toupper();) P213

     

    6.7 其他STL容器

    1. STL是一个框架。使用其它数据结构定义容器的三种不同方法:P217

    (1)侵入式:直接提供STL所需接口,如begin(),end()之类的常用函数。这种方法是以某种特定方式编写容器,所以叫侵入式。  

    (2)非侵入式:只提供特殊的迭代器作为算法与特殊容器的界面,只需遍历容器所有元素的能力。

    (3)包装法:上述两种方法的组合,将一个数据结构包装出于STL容器相似的接口。

    2. 将数组包装成array容器的实例。 P219

     

    6.8 动手实现reference语义

    使用引用计数的智能指针作为容器的元素。

     

    6.9 各容器的运行时机

    P226

     

    6.10 细说容器内的型别和成员

    1. 容器内的型别:reference, const_reference, iterator, const_iterator, reverse_iterator, const_reserve_iterator, size_type, difference_type, value_type, key_type, mapped_type, key_compare, value_compare, allocator_type.

    2.  Constructor, Copy, Destructor :  P231

    3. Nomodifying Operations :  P233

    4. Assignments:  operator=, assign(), swap().

    5. 返回元素:front(), back(), at(), operator[].

       返回迭代器:begin(), end(), rbegin(), rend().

    6. Inserting 、 Removing : P240

    7. Lists的特殊成员函数:unique(), splice(), merge(), sort(), reverse().

    8. STL容器的异常处理: P249

     

    第七章 STL Iterator

    7.1 迭代器头文件: <iterator>容器本身已包含该头文件。

     

    7.2 迭代器类型: InputOutputForwardBidirectionalRandom access

     

    7.3 迭代器相关辅助函数:

           //使迭代器前进n步,n可以为负数

    1. #include<iterator> void  advance(InputIterator&  pos, Dist  n);

       //返回两迭代器之间的距离

    2. #include<iterator> Dist  distance(InputIterator  pos1,  InputIterator  pos2);

           //交换两个迭代器所指元素的内容

    3. #include<algorithm> void  iter_swap(ForwardIterator pos1, ForwardIterator pos2);

     

    7.4 迭代器适配器

    1. 逆向迭代器:逆向迭代器指向的是实际元素位置,返回的是所指位置的下一跳的值。

    例:begin()rend()所指位置相同,但是rend()取值返回的是begin()所指位置的前一个;end()rbegin()所指位置相同,但是rbegin()取值返回的是end()所指的起一个元素。

    逆向迭代器直接用一般迭代器初始化:pos=v.begin(); vector<int>::reverse_iterator rpos(pos);

    逆向迭代器转化为正向迭代器使用成员函数:pos = rpos.base();

    2. 安插型迭代器:

    名称

    Class

    其所调用的函数

    生成函数

    Back inserter

    back_insert_iterator

    push_back(value)

    back_inserter(coll)

    Front inserter

    Front_insert_iterator

    push_back(value)

    front_inserter(coll)

    General inserter

    Insert_iterator

    insert(pos, value)

    inserter(coll, pos)

    3. 流迭代器

    Ostream迭代器:template ... class ostream_iterator;

    Istream迭代器: template ... class istream_iterator;

    所有istream迭代器只要任何一次读取失败都会变成end-of-stream,所以每进行一次读取都都应将istream迭代器与end-of-streamistream迭代器的default构造函数生成)比较,检查这个迭代器是否合法。

     

    7.5 迭代器特性

    template <class T>

    struct iterator_traits {

    typedef  typename  T::value_type            value_type;

    typedef  typename  T::difference_type        difference_type;

    typedef  typename  T::iterator_category       iterator_category; 

    typedef  typename  T::pointer               pointer;

    typedef  typename  T::reference             reference;

    };

     

    第八章 STL Function objects

    8.1 函数对象(或叫仿函数functor)的概念: 定义了operator()的对象。

    函数对象比一般函数更灵巧,因为它可以拥有状态,而且不止一个状态;

    函数对象是class,有型别的。所以可以将它当做template参数传递;

    执行速度上函数对象通常比一般函数快。

    函数对象做函数参数传递时是passed by value,而不是reference!若需传递reference则要对template参数进行特化: 

    generate_n<back_insert_iterator<list<int> >, int, Functor&>( back_inserter(coll),  4,  seq);

     

    8.2 预定义的函数对象 P305#include<functional>

    1. 函数适配器:指能将两个函数对象结合起来的函数对象(函数复合)bind1st, bind2nd, not1, nos2 

    2. mem_fun_ref, men_fun(不能直接将一个成员函数传给一个算法,需要运用适配器,这两者调用的成员函数必须是const) 

    3.  ptr_fun(针对非成员函数)

     

    8.3 辅助用(综合型)函数对象:实现多个函数对象的组合使用,如:A and B

    1. 一元组合函数适配器

    2. 二元组合函数适配器

     

    第九章 STL Algorithm

     

     

    第十章 STL Special Containers

    10.1 Stack

    Namespace std {

    Template <class T, class Container = deque<T> >

    Class stack; }

     

    核心接口:push()   top()    pop()

     

    10.2 Quene

    Namespace std {

    Template <class T, class Container = deque<T> >

    Class queue; }

     

    核心接口:push()   front()     pop()    back()

     

    10.3 Priority Queue

    Namespace std {

    Template <class T, class Container = vector<T>,

    Class comjpare = less<typename Container::value_type> >

    Class priority_queue; }

     

    核心接口:push()     top()    pop()

     

    10.4 Bitset

    Bitset是容量不可变得位集,vector<bool>则是动态位集。

    Namespace std {

    Template <size_t  Bits>

    Class bitset; }

     

     

     

     

  • 相关阅读:
    zabbix入门知识
    flask_login
    flask_数据库
    flask_web表单
    flask_模板
    flask_hello world
    1024 Hello World
    使用bat批处理文件备份postgresql数据库
    使用bat批处理文件备份mysql数据库
    在windows7下创建ftp服务站点
  • 原文地址:https://www.cnblogs.com/songcf/p/3043063.html
Copyright © 2020-2023  润新知