练习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;
}

运行的结果为:操作系统

从运行结果能够看出:.net

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

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

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

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

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

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

 

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

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

相关文章
相关标签/搜索