练习13.13的一个有意思的现象

  在做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;
}

运行的结果为:

从运行结果可以看出:

添加第一个元素时,只调用了一次X的拷贝构造函数;

添加第二个元素前,此时的capacity为1,所以要为容器扩容,扩容后为2,添加第二个元素时,却调用了两次拷贝构造函数,最后调用析构函数销毁扩容前的第一个元素;

添加第三个元素时,也同理,重新构造了前两个已经构造的元素,再构造第三个元素添加至末尾;

添加第四个元素前,capacity为4,足够再添加多一个元素,则只调用了一次拷贝构造函数;

添加第五个元素前,capacity与size一致,需要扩容,则容器重新构造了前四个元素,然后再构造第五个元素添加至末尾,最后销毁扩容前构造的四个元素;

程序结束退出,调用5次析构函数销毁vector内的5个元素。

另外参考了一篇文章:http://blog.csdn.net/mfcing/article/details/8746256

这篇文章详细说明了——关于vector,简单地讲就是一个动态数组,里面有一个指针指向一片连续的内存空间,当空间不够装下数据时会自动申请另一片更大的空间,然后把原有数据拷贝过去,接着释放原来的那片空间;当释放或者说是删除里面的数据时,其存储空间并不会释放,仅仅只是清空了里面的数据。

原文地址:https://www.cnblogs.com/ChenZhongzhou/p/5388573.html