最近在看 effective c++ 看了一会放置忘记先记下 积累才是做程序的本钱。
区间成员函数是指这样一类成员函数:他们像STL算法一样使用两个迭代器参数来确定该成员操作操作所执行的区间。
如:给定v1与v2两个向量(vector),使v1的内容和v2的后半部分相同的方法为:
方法1 v1.assign( v2.begin() + v2.size() / 2 , v2.end()); 最简单的方法 也是最推荐的方法
方法2 循环v2 然后 v1.push_back(*iter) 这样不止是比assingn 做的工作多这么简单
方法3 v1.insert( v1.end() , v2.begin() + v2.size() / 2 , v2.end() ); 推荐的方法
方法4 copy( v2.begin() + v2.size() /2 , v2.end() , back_inserter(v1) );
拷贝数组 vector<int> v ; int data[numvalues];
v.insert( v.begin() , data , data + numvalues );
分析 区间成员函数调用与之对应的单元素成员函数调用问题
问题:把n个元素的插入v向量(vector)
1.不必要的函数调用 区间操作一次搞定 , 单个元素插入会导致n次调用insert
2.单个插入v的前端 v中的每个元素会向后移动n次 插入前有numvalues个元素的话就需要移动numvalue*n次
每次调用终归调用memmove 如果存取的是用户自己定义的类型 则每次移动会导致调用该类型的赋值操作符或拷贝构造函数(大多数是赋值操作符,但是每次vector最后一个元素被移动时会调用钙元素的拷贝构造函数)。
所以把numvalues个元素插入到含有n个元素的vector<Widget>的全段会有 n*numvalues 次函数调用的代价 (n-1)*numvalues次调用Widget赋值操作符和numvalues次调用Widget拷贝构造函数
与此同时c++标准的insert函数把现有的容器的元素直接移动到它们最终的位置上只需要附出每个元素移动一次的代价 包括 n次移动、numvalues次调用该容器中元素的赋值操作符 和 拷贝构造函数。
3.可能导致内存重新分配很多次 比如vector 没插入一次如果vector满了的话会导致重新分配加倍的内存并且把旧的内存拷贝到新的内存,销毁掉旧内存中的元素,释放旧的内存
1000个元素会导致10次的内存重新分配 与之对应的区间函数插入的话在插入之前就知道自需要多少内存避免了重新分配内存。
注意:次分析方法对string同样有效
总结下:
区间创建:所有的标准容易都提供了如下形式的构造函数:
container::container( InputerIterator begin , 区间的开始
InputerIterator end );区间的结束
区间插入:所有的标准序列容器都提供了如下形式的insert:
void container::insert( iterator position , 在何处插入区间
InputIterator begin,区间开始
InputIterator end);区间结束
区间删除: 所有的标准容器都提供了区间删除(erase)操作,但对于序列和关联容器,其返回值有所不同序列
序列容器 : iterator container::erase( Iterator begin , Iterator end );
关联容器: void container::erase( iterator begin , iterator end);
区间赋值:
void container::assign( InputIterator begin , InputIterator end );