在作C++ Primer 5th的联系13.13时有一个颇有意思的现象:当一个声明一个保存自定义类类型的vector时,若是在进行push_back操做以前这个vector的capacity和其size一致的话,则程序会向操做系统申请更多的内存以保存更多的元素。此时,整个vector会对其已经构建的元素从新所有构建一次(即调用拷贝构造函数),而后再在末尾元素以后构建新的元素。最后调用析构函数销毁扩容以前构建的元素。数组
下面直接看程序:函数
//X结构体的定义 struct X { //默认构造函数 X() { cout << "X()" << endl; } //拷贝构造函数 X(const X&) { cout << "X(const X&)" << endl; } //拷贝赋值运算符 X& operator=(const X&) { cout << "operator=(const X&)" << endl; } //析构函数 ~X() { cout << "~X()" << endl; } }; int main(int argc, char** argv) { vector<X> vec_X; //vec_X.reserve(3); //若是不进行预留空间 //则vector进行push_back的时候 //会重复构建以前已经push_back的元素 for(unsigned i = 0; i < 5; ++i) { X temp_x; //调用默认构造函数 vec_X.push_back(temp_x); //void push_back ( const T& x ); //传参时,调用拷贝构造函数,构造一个对象 //添加到vector的末尾 cout << vec_X.capacity() << " "; //离开for循环,temp_x被销毁,调用析构函数 } cout << endl; return 0; }
运行的结果为:操作系统
从运行结果能够看出:.net
添加第一个元素时,只调用了一次X的拷贝构造函数;指针
添加第二个元素前,此时的capacity为1,因此要为容器扩容,扩容后为2,添加第二个元素时,却调用了两次拷贝构造函数,最后调用析构函数销毁扩容前的第一个元素;对象
添加第三个元素时,也同理,从新构造了前两个已经构造的元素,再构造第三个元素添加至末尾;blog
添加第四个元素前,capacity为4,足够再添加多一个元素,则只调用了一次拷贝构造函数;内存
添加第五个元素前,capacity与size一致,须要扩容,则容器从新构造了前四个元素,而后再构造第五个元素添加至末尾,最后销毁扩容前构造的四个元素;ci
程序结束退出,调用5次析构函数销毁vector内的5个元素。it
另外参考了一篇文章:http://blog.csdn.net/mfcing/article/details/8746256
这篇文章详细说明了——关于vector,简单地讲就是一个动态数组,里面有一个指针指向一片连续的内存空间,当空间不够装下数据时会自动申请另外一片更大的空间,而后把原有数据拷贝过去,接着释放原来的那片空间;当释放或者说是删除里面的数据时,其存储空间并不会释放,仅仅只是清空了里面的数据。