• 练习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,简单地讲就是一个动态数组,里面有一个指针指向一片连续的内存空间,当空间不够装下数据时会自动申请另一片更大的空间,然后把原有数据拷贝过去,接着释放原来的那片空间;当释放或者说是删除里面的数据时,其存储空间并不会释放,仅仅只是清空了里面的数据。

  • 相关阅读:
    【语言处理与Python】6.3评估
    win10同时安装 office2016和visio2016
    如何学好C语言(转)
    数据库索引
    Redis系列(二)如何接受客户端请求并调用处理函数
    Redis系列(三)事件处理细节分析及epoll介绍
    linux下查看某一个程序所使用的内存方法总结
    c++ 二级指针详解&&hiredis api
    C风格字符串
    twemproxy简介
  • 原文地址:https://www.cnblogs.com/ChenZhongzhou/p/5388573.html
Copyright © 2020-2023  润新知