vector的成员函数resize分析

来源:互联网 发布:linux中excel函数用法 编辑:程序博客网 时间:2024/06/08 13:14

一直以为一个class的vector,当进行resize操作的时候,会调用n次构造函数。但其实不是,无论resize(n)中的n有多大或是多小,

在进行resize操作的时候仅仅只会调用一次构造函数。

比如下面的例子:

源码:

/* *vec.cpp */#include <vector>#include <iostream>using namespace std;class A{    public:        A(){cout<<"create."<<endl;}        ~A(){cout<<"destory."<<endl;}};int main(){    vector<A> vecA;        cout<<"resize(10)"<<endl;    vecA.resize(10);        cout<<"resize(5)"<<endl;    vecA.resize(5);    cout<<"end."<<endl;    return 0;}
输出:

resize(10)create.destory.resize(5)create.destory.destory.destory.destory.destory.destory.end.destory.destory.destory.destory.destory.

分析原因:
resize的源码如下:

      /**         *  @brief  Resizes the %vector to the specified number of elements.       *  @param  new_size  Number of elements the %vector should contain.       *  @param  x  Data with which new elements should be populated.       *       *  This function will %resize the %vector to the specified       *  number of elements.  If the number is smaller than the       *  %vector's current size the %vector is truncated, otherwise       *  the %vector is extended and new elements are populated with       *  given data.       */      void       resize(size_type __new_size, value_type __x = value_type())      {    if (__new_size > size())  insert(end(), __new_size - size(), __x);else if (__new_size < size())  _M_erase_at_end(this->_M_impl._M_start + __new_size);      }
我们发现,在resize开始的时候就会构造一个临时的class A的变量,不妨设为tmpA。
如果__new_size > size(),就会进行insert的操作,其实insert的实现是这样的(伪代码):

bool insert(iterator _pos, int _size, A tmpA){//申请空间A *listA = (A *)malloc(sizeof(A)*_size);//赋值for(int i=0; i<_size; i++){memcpy(listA+i, &tmpA, sizeof(A));}//将listA中的各个元素链接到vector中...}

如果__new_size < size(),就会进行erase操作,直接调用相应的析构函数就ok啦,
最后同样不要忘了tmpA的析构。