《Effective STL》 05 区间成员函数优先于与之对应的单元素成员函数

讨论:给定v1和v2两个矢量(vector),使v1的内容和v2的后半部分相同的最简单操作如何实现?

    方案1:v1.assign(v2.begin()+v2.size()/2,v2.end());

    方案2:v1.clear();   copy(v2.begin()+v2.size()/2,v1.end(),back_inserter(v1));

    方案3:使用循环将所需要插入的元素一个一个地插入到目标容器中。

    vector<int>::iterator insertLoc(v.begin());
    for(int i=0;i<numValues;i++)
    {
        insertLoc=v.insert(insertLoc,data[i]);
        ++insertLoc;
    }

方案3中必须要实时更新insertLoc的值,否则可能会有两个方面的问题:1)如果不实时更新insertLoc的值,那么第一次循环后,insertLoc可能会失效,导致后面的循环无法进行。2)即使该值是有效的,但是由于不更新该值,那么元素都将会插入在容器的最前端。

    上面三种方案中最合适的方案首选方案一。这也是这篇博文的主题:区间成员函数优先于单元素的成员函数。

    方案三中需要调用numValues次insert()函数,而方案一中只需要调用一次足矣。insert()函数的操作是每次插入一个元素或者多个元素时,需要从插入位置开始,后面的每一个元素都需要向后移动若干个位置。所以方案3中,每次有需要insertLoc后面的每个元素向后移动一个位置,一共需要移动numValues次。虽然方案1和方案3移动的位置个数相同,但是方案1一次就可以把所有的位置腾出来,而方案3却需要多次挪动,会降低程序的执行效率。对于用户自定义的数据类型,比如用户自己定义的类,那么就不仅仅是移动位置这么简单了。在每次移动中,还需要执行拷贝构造函数和赋值操作符。以上面的问题为例,那么如果单元素插入的话,共需要调用(n-1)*numValues次构造函数和赋值操作符。那么两部分的时间加在一起就是不小的时间开销。

    另外当vector开始分配的内存已满,那么vector会自动增加内存大小,同时再把原来旧容器中的元素装到新容器中,并把旧容器的内存释放掉。上面针对vector的分析同样适用于deque和string,但是在内存管理上deque和vector不同,关于内存管理的分析则不再适用。


    

    上图是容器list的数据结构,每次有新的节点在A节点前插入时,A会把其pre指针指向新指针。如果在A节点前面插入numValues个指针,那么,对所有插入的节点的next指针就会有numValues-1次是多余赋值的。同理,如果是一个一个插入那么A节点的pre指针也要多余赋值numValues次。



区间创建:所有的标准容器都提供如下形式的构造函数:

                container::container(InputIterator  begin,//区间开始

                                                       InputIterator  end);//区间结束


区间插入:所有的标准序列容器都提供如下形式的insert:

                void container::insert(iterator position,             //在何处插入区间

                                                 InputIterator begin,        //区间开始

                                                 InputIterator end);         //区间结束

区间删除:所有的标准容器都提供区间形式的删除操作,但对于序列和关联容器,其返回值有所不同。

                iterator container::erase(iterator begin,iterator end);

                而关联容器则提供如下形式:

                void container::erase(iterator begin,iterator end);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值