zoukankan      html  css  js  c++  java
  • STL源码剖析读书笔记之vector

    STL源码剖析读书笔记之vector

    1.vector概述

    vector是一种序列式容器,我的理解是vector就像数组。但是数组有一个很大的问题就是当我们分配

    一个一定大小的数组的时候,起初也许我们不会觉得数组容量太小不合需求,但是随着数据量的增加,

    数组尺寸大小不再满足需求,此时我们需要手动的去扩展其大小。然而vector就帮我们完全实现了一个可

    自适应增长的数组功能。那么这样看来vector其实也就是一种可自适应增长的动态数组的类的实现。

     

    2.关于vector的定义

    其实用过vector的人都知道 vector的定义大都像这个样子:

    1 vector<int> v1;
    2 vector<sting> v2;

    很显然vector是一种与类型无关的类模板,支持各种类型的vector,这也很好的体现了C++的泛型思想,正

    是这种类型无关性,使得STL在各种平台上广为使用。

     

    这里我只是贴出STL源码剖析书中一小部分vector定义

     1 template <class T,class Alloc=alloc>
     2 class vector
     3 {
     4 public:
     5    typedef   T     value_type;
     6    typedef valuetype* pointer;
     7    typedef valuetype* iterator;  
     8    typedef valuetype& reference;
     9    typedef size_t    size_type;
    10 ......
    11 protected:
    12      iterator start;
    13      iterator finish;
    14      iterator end_of_storage;
    15 ....
    16 pubic:
    17      iterator begin{return start;}
    18      iterator end(){return finish;}
    19      size_type size() const {return size_type(end()-begin());}
    20      size_type capacity() const {return size_type(end_of_storage-begin());}
    21      reference front {return *begin()}
    22  }

    上面有几个关键点:

    vector维护了三个迭代器:start,finish和end_of_storage由typedef valuetype* iterator可知迭代器说白

    了就是指针。那么vector维护的三个迭代器(指针)的意思是什么呢。start指向vector的第一个元素。finish

    指向vector已经使用的空间的最后一个元素的下一个元素。end_of_storage指向vector总共可用空间的最后

    一个元素的下一个元素所以操作vector与操作指针完全类似,只是在vector中把这些操作封装成相应的方法

    直接供读者使用罢了。

    3.vector内存分配原理

    不是之前我们说vector是一种自增长的动态数组吗?那么其子增长的原理是什么。

    其实很简单:

    1.当vector为空时,我们插入一个元素到vector中,这时候vector将内存容量变为1,然后将新的元素插入其中

    2.当vector容量为1的时候,此时vector中刚好有一个元素,若要插入一个2,这时候将重新new一个内存为2的新

    间,将之前内存中的1拷贝到新内存并释放1旧内存,同时将新的元素2插入其中

    3.重复步骤2,只要就内存容量已满就重新分配新内存,新内存的大小是旧内存的二倍,再讲旧内存中的数据

    值到新内存,同时释放新内存。同时插入新元素在新的内存空间。

     

    我们可以用下面的程序验证这一点:

     1 #include <iostream>
     2 #include <vector>
     3 using namespace std;
     4 
     5 int main(int argc, char* argv[])
     6 {
     7     std::vector<int> v1;
     8     
     9     cout<<"v1.size()="<<v1.size()<<"   "<<"v1.capacity()="<<v1.capacity()<<endl;
    10     v1.push_back(1);
    11     cout<<"v1.size()="<<v1.size()<<"   "<<"v1.capacity()="<<v1.capacity()<<endl;
    12     v1.push_back(2);
    13     cout<<"v1.size()="<<v1.size()<<"   "<<"v1.capacity()="<<v1.capacity()<<endl;
    14     v1.push_back(3);
    15     cout<<"v1.size()="<<v1.size()<<"   "<<"v1.capacity()="<<v1.capacity()<<endl;
    16     v1.push_back(4);
    17     cout<<"v1.size()="<<v1.size()<<"   "<<"v1.capacity()="<<v1.capacity()<<endl;
    18     v1.push_back(5);
    19     cout<<"v1.size()="<<v1.size()<<"   "<<"v1.capacity()="<<v1.capacity()<<endl;
    20     return 0;
    21 }

    截图如下:

    此外,有几个问题需要注意:

    1.为什么vector容量满了之后要重新开辟新的内存,因为vector要求连续的内存空间

    2.如果重新开启新内存太频繁应该会造成较大的程序开销,怎么办.我们可以一开给reserve一个大的capacity.

    3.重新开启新内存是否会造成原来的迭代器失效 ?是的,所以我们最好知道何时会开辟新的capacity,进而防止这种迭代器失效。

    4.对于vector删除或者插入造成的迭代器失效已经在之前的博文中有介绍。

     

     

  • 相关阅读:
    C# .NET5.0 平台介绍、演变
    ORA01034/ORA27101解决
    navicat无法连接虚拟机MySQL
    [原创]Windows下Google V8 javascript引擎编译
    CentOS 6.9安装MySQL5.5
    国内yum源
    【转】关于C++程序的编码问题
    VS C4819 编译错误解决方法
    Windows下Vundle安装
    vmware NAT 静态ip配置
  • 原文地址:https://www.cnblogs.com/vpoet/p/4667226.html
Copyright © 2011-2022 走看看