zoukankan      html  css  js  c++  java
  • 初识STL

    原生指针 泛型指针 智能指针 都是什么?

    iterator迭代器和指针的区别

    C++标准模板库(STL)迭代器的原理与实现

    【C++】STL常用容器总结之一:容器与迭代器

    C++内置数组和array的比较

      STL(Standard Template Library,标准模板库)六大组件:容器,算法,迭代器,仿函数,适配器,空间配置器。

    容器

      STL容器即将数据结构实现出来,根据“数据在容器中的排列”特性,这些数据结构可分为序列式和关联式两种。从实现角度看,容器为class template.

    容器分类 

      容器大概也分为序列式容器和关联式容器两种。 

      所谓序列式容器,又叫顺序容器,其中的元素都可序(ordered),但未必有序(sorted),元素在顺序容器中的顺序与其加入容器时的位置相对应(遍历时可以根据位置顺序来访问?通过迭代器自增访问?)。

      所谓关联式容器,即元素的位置由元素相关联的关键字值决定(关联式容器如何进行访问,通过迭代器的话,是类似序列容器的自增吗?)。

    算法

      各种常用算法的实现与封装,如,查找,排序,拷贝,删除等。从实现角度来看,STL算法是一种function template.

    迭代器

      迭代器,在设计模式中有一种模式叫迭代器模式,简单来说就是提供一种方法,在不需要暴露某个容器的内部表现形式情况下,使之能依次访问该容器中的各个元素,这种设计思维在STL中得到了广泛的应用,是STL的关键所在,通过迭代器,容器和算法可以有机的粘合在一起,只要对算法给予不同的迭代器,就可以对不同容器进行相同的算法操作,即只要容器提供迭代器的接口,同一套算法代码可以利用在完全不同的容器中。从实现角度看,迭代器是一种将*,->,++,--等指针相关操作予以重载的class template,比指针更丰富的功能。

    容器的迭代器类型

      每种容器类型都定义了自己的迭代器类型,如vector,vector<int> ::iterator iter;变量名为iter。迭代器并不是独立的数据类型,必须添加容器作用域后才能确定类型,vector的迭代器为指针,list的为类。

      下面是从网上看到的一段代码,最开始没反应过来,实际问题为:it为vector<int>类型,而不是int类型,之所以对it取*可以访问元素,是对*进行了重载。

     1 class A
     2 {
     3     public:
     4         int* GetA(int b)
     5         {   
     6             for(std::vector<int>::iterator it = _a.begin(); it != _a.end(); ++it)
     7             {   
     8                 if((*it) == b)  
     9                     return &(*it); //这里如果直接返回迭代器it会报错 所有取内容然后取地址返回不会报错 
    10             }   
    11             return NULL;
    12         }   
    13      
    14         void SetA(int b)
    15         {   
    16             _a.push_back(b);
    17         }   
    18     private:
    19         std::vector<int> _a; 
    20 };

    迭代器的begin和end操作

    1 int main()
    2 {
    3     vector <int> v{ 1,20,10,5,6,7,90 };
    4 
    5     auto beg = v.begin();
    6     auto end = v.end();
    7 }

      迭代器和指针不一样,容器有迭代器类型同时拥有返回迭代器的成员。比如,容器都有的成员begin和end,其中begin成员返回指向第一个元素的迭代器,而end成员返回指向容器尾元素的下一个位置的迭代器。end操作返回的迭代器并不指向vector中任何实际的元素,它只是起到一个哨兵的作用,表示我们已经处理完vector中的所有元素。 

      如果容器为空,则begin和end返回的是同一个迭代器,都是尾后迭代器。另外,我们不在意迭代器的类型,因此可以通过auto数据类型接收迭代器类型。

    迭代器与指针

      1)本质不同,迭代器是类模板,指针是存储数据地址的变量;

      2)迭代器是广义上的指针,类似“智能指针”。事实上,它可以是指针,也可以是一个对其执行类似指针的操作的对象,如解除引用(如operator*())和递增(如operator++());

      3)指针能指向函数而迭代器不行,迭代器只能指向容器;

      4)原生指针也是一种迭代器(解释需要涉及STL源码解析),指针只能用于某些特定的容器;

      5)迭代器使用时,通过begin和end成员返回迭代器,而指针通过取地址符获取空间地址。

    注意:在用迭代器执行erase,insert等函数时,迭代器的指针会被释放掉,从而不能继续使用,如果继续使用,则会报错,适用于vector(可能还有其他??)。

    原生、泛型、智能指针

      1) 原生指针

        就是最普通的指针,定义类似: 类型 *变量名;

        与之对比的是使用上有类似指针的功能 实际并不是指针。比如:迭代器

        [一个类重载 *和->操作符 那么可以像指针一样使用  但是这种并不是原生的]

      2) 泛型指针

        第一种就是 void *指针 可以指向任意的数据结构 因此可以称为"泛型"。

        第二种就是指具有指针特性的泛型数据结构 如:泛型迭代器和接下来要说的智能指针。

      3) 智能指针

        C++中没有自动回收内存的机制,因此出现了智能指针。 一般我们将一个指针封装到一个智能指针类中,该类中有一个引用计数器。对指针的复制等操作会使引用计数+1,delete操作会使引用计数-1。计数=0时,指针=NULL。

    迭代器遍历元素的注意事项

      在for循环内遍历容器元素时,结束判断条件尽量不要使用<,尽量使用!=

     1 void test001(){
     2     vector<int>tmp;
     3 
     4     for (int i = 0; i < 10; i++){
     5         tmp.push_back(i);
     6     }
     7     
     8     for (vector<int>::iterator ite = tmp.begin();
     9         ite < tmp.end(); ite++){
    10         cout << *ite << endl;
    11     }
    12     //尽量采用下面的!=而不是<,因为所有的标准库容器中都定义了==和!=,他们中的大多数都没有定义<运算符
    13     for (vector<int>::iterator ite = tmp.begin();
    14         ite != tmp.end(); ite++){
    15         *ite = 1;
    16         cout << *ite << endl;
    17     }
    18 }
    仿函数
      从实现角度来看,仿函数是一种重载了()的class或class template,一般函数指针可视为狭义的仿函数。
    适配器
      用来修饰容器、仿函数、迭代器接口的东西。设计模式中也有adapter的概念。将一个class的接口转换为另一个class的接口,使原本因接口不兼容而不能合作的class,可以一起运作。
    空间配置器
      负责空间配置与管理。从实现角度来看,配置器实现了动态空间配置、空间管理、空间释放的class template。

    关于内置数组array和STL中的array

      array是C++11中新提出来的容器类型,与C++内置数组(内置array)相比,array是一种更容易使用,更加安全的数组类型,可以用来替代内置数组。
  • 相关阅读:
    JS: 子项可以来回交换的两个下拉列表
    DOM事件
    DOM基础2——元素
    DOM基础1
    JS: 随机点名程序与万年历
    G_S男女匹配算法(算法的第一个程序2016.09.19)
    Java IO流详尽解析(大神之作)
    细讲解JAVA中的IO流
    c++运算符的优先级(收好不谢)
    java程序——输出当月日历表
  • 原文地址:https://www.cnblogs.com/qinguoyi/p/10398161.html
Copyright © 2011-2022 走看看