C++ vector使用的一些注意事项

 更新时间:2019年08月14日 10:15:53   作者:Leehm  
这篇文章主要给大家介绍了关于C++ vector使用的一些注意事项,文中通过示例代码介绍的非常详细,对大家学习或者使用C++具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

1. 初始化

       c++ 11以后新增了大括号{}的初始化方式,需要注意与()的区别,如:

         std::vector<int> vecTest1(5);         //初始化5个元素,每个都是0

         std::vector<int> vecTest2{ 5 };       //初始化1个元素,值是5

 

2.  添加元素:push_back

       通过push_back添加新的元素进入vector后,vector的内存有时候会发生变化,这取决于size和capacity大小,当然这些都是系统来处理的,详细可以参考stl源码

        当size<capacity的时候,直接加到末尾,不会变化

        当size==capacity的时候,会重新申请另外一块内存,然后copy过去加到尾部,这个时候就会有变化了。

        对于stl的容器,都有成员:

                 begin()  //起始位置

                 end() //结束位置

                 size() //当前大小

         capacity() //当前容量,即已申请的内存大小

     vector是一段连续的内存空间,有三个标识内存的位置,start,end,finish, size=end-start, capacity=finish-start

     很多时候在使用vector的时候,会看到size=capacity,这个时候直接添加元素到尾部,内存明显是不够的,此时会重新在别处分配一块大小足够

     有时候也有size<capacity, 这个时候就直接加在尾部了。

std::cout << "vecNum push back init" << std::endl;
vector<int> vecNum(5);
std::cout << "vecNum addr: " << &vecNum << std::endl;
for(auto i = 5; i < 10; i++)
{
 vecNum.push_back(i*10);
 std::cout << "vecNum push_back(" << i << ")=" << i*10 << std::endl;
 
 std::cout << "vecNum.size() = " << vecNum.size() << ",vecNum.capacity() = " << vecNum.capacity() << std::endl;
 std::cout << "vecNum.begin() addr: " << &(*vecNum.begin()) << std::endl;
}
std::cout << "vecNum addr: " << &vecNum << std::endl;

3. 关于earse和remove

     erase返回的是当前删除的元素的一下个位置的迭代器,所以需要注意的是遍历时候的++运算,这个与其它list,map差不多,

    需要注意的earse后内存并未真正的清空,仅仅是删除内容,真正的容量大小capacity并没有改变,需要通过swap来实现capacity的减小

     全部清空可以考虑:vector<int>().swap(vecNum);

auto itor = vecNum.begin();
for( ; itor != vecNum.end(); )
{
 auto num = *itor;
 if(num == 60)
 {
 itor = vecNum.erase(itor);
 break;
 }
 else
 {
 itor++;
 }
}

 std::cout << "after erase element 60:" << std::endl;
 printVector(vecNum);
 vector<int>(vecNum).swap(vecNum); //将vecNum的内存空洞清除
 printVector(vecNum);

      //remove只是通过迭代器的指针向前移动来删除,将不需要删除的元素往前移,因此需要删除的就都在尾部了

      //返回新的指向尾部需要删除的元素的迭代器

      因此还是得配合earse来使用,所以一般真要删除,建议直接遍历使用earse

auto itor = remove_if(vecNum.begin(), vecNum.end(),[](int x)->bool{ return x == 20; });
//or
//auto itor = remove(vecNum.begin(), vecNum.end(),20);
 
//通过erase删除
vecNum.erase(itor, vecNum.end());

4. 关于vector< bool>  -- 慎用

       出处: https://www.jb51.net/article/167636.htm

       vector< bool> 并不是一个STL容器,不是一个STL容器,不是一个STL容器!

       首先vector< bool> 并不是一个通常意义上的vector容器,这个源自于历史遗留问题。

早在C++98的时候,就有vector< bool>这个类型了,但是因为当时为了考虑到节省空间的想法,所以vector< bool>里面不是一个Byte一个Byte储存的,它是一个bit一个bit储存的!

因为C++没有直接去给一个bit来操作,

    所以用operator[]的时候, 正常容器返回的应该是一个对应元素的引用,

   但是对于vector< bool>实际上访问的是一个”proxy reference”而不是一个”true reference”,返回的是”std::vector< bool>:reference”类型的对象。

   因此,使用auto自动类型推导时会出现问题

//vector<bool>慎用
	vector<bool> vecBool = { false, true, false };
	bool test1 = vecBool[0]; 
	auto test2 = vecBool[1];
	test1 = true; //test1的初始化它其实暗含了一个隐式的类型转换(直接对vecBool[0]赋值会修改vecBool中的值,但是对test1不会)
	test2 = false; //test2它的类型并不是bool,而是一个vector< bool>中的一个内部类,而此时如果修改test2的值,vecBool中的值也会跟着修改
	auto index = 0;
	for (auto i : vecBool)
	{
 cout << "vecBool[" << index << "]" << i << std::endl;
 index++;
	}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

相关文章

  • C++实现strcmp字符串比较的深入探讨

    C++实现strcmp字符串比较的深入探讨

    本篇文章是对使用C++实现strcmp字符串比较进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 华为面试题答案找出最大长度子字符串

    华为面试题答案找出最大长度子字符串

    找出最大长度子字符串,打印并且返回长度。 例如 str = "abc123abcd234abcdefgha324adsdawqdasdaseqqwe345abchded",看下面的代码实现吧
    2013-12-12
  • 函数外初始化与函数内初始化详细解析

    函数外初始化与函数内初始化详细解析

    函数内初始化:bool FillStr(char *&szDst, int nSize);第一个参数中的&一定不能少,这是因为在函数外部我们只声明了这个指针,具体这个指针指向内存中的哪个地址我们并不知道,所以&是为了说明传递的是这个指针的引用,那么在函数内初始化后这个指针的地址也就是外面指针的地址了
    2013-09-09
  • C语言 数据结构之中序二叉树实例详解

    C语言 数据结构之中序二叉树实例详解

    这篇文章主要介绍了C语言 数据结构之中序二叉树实例详解的相关资料,需要的朋友可以参考下
    2017-01-01
  • C++的sstream标准库详细介绍

    C++的sstream标准库详细介绍

    以下是对C++中的的sstream标准库进行了详细的介绍,需要的朋友可以过来参考下
    2013-09-09
  • C++遍历文件夹下所有文件的多种方法

    C++遍历文件夹下所有文件的多种方法

    这篇文章主要介绍了C++遍历文件夹下所有文件的多种方法,需要的朋友可以参考下
    2018-01-01
  • C语言实现简单计算器功能(1)

    C语言实现简单计算器功能(1)

    这篇文章主要为大家详细介绍了C语言实现简单计算器功能的第一部分,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • C基础 mariadb处理的简单实例

    C基础 mariadb处理的简单实例

    下面小编就为大家带来一篇C基础 mariadb处理的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • C语言实现消消乐小游戏

    C语言实现消消乐小游戏

    这篇文章主要为大家详细介绍了C语言实现消消乐小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • 关于在C程序中处理UTF-8文本的方法详解

    关于在C程序中处理UTF-8文本的方法详解

    这篇文章主要给大家介绍了关于在C程序中处理UTF-8文本的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-11-11

最新评论