应用到类的指针上,意思是说它允许子类类型的指针转换为父类类型的指针(这是一个有效的隐式转换),同时,也能够执行相反动作:转换父类为它的子类。... 双端队列deque 基本上与向量相同,唯一的不同是,其在序列头部插入和删除操作也具有常量时间复杂度 表list 对任意元素的访问与对两端的距离成正比,但对某个位置上插入和删除一个项的花费为常数时间...c.push_back(elem); c.pop_back(); c.erase(pos); 删除pos上的元素,返回下一个元素 c.erase(beg,end); c.resize(num);将元素数量改为...vector的reserve和resize reserve只分配空间,而不创建对象,size()不变。...remove从一个容器中remove元素不会改变容器中元素的个数,erase是真正删除东西。 13、提防在指针的容器上使用类似remove的算法,在调用类似remove的算法前手动删除和废弃指针。
组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。数组是在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来的一种形式。...char a4[6] = "hello"; // 报错,没有 null 的位置 数组的大小是固定的,不能额外增加元素,当想定义不固定大小的字符时,使用vector vector vec;...} } 遍历元素 当然,你可以使用数组下标形式访问元素,因为vector重载了 [] 操作,不过不建议。...我也不知道为什么有人要就这些区别长篇大论。 begin():指向容器的第一个元素的地址。 front():指向容器的第一个元素的值。...vector> //vector类相关 #include //容器算法 vector的元素不仅仅可以是int,double,string,还可以是结构体,但是要注意:结构体要定义为全局的
,这就是为什么我们用类封装的原因。...= end()) { it = erase(it);//不更新it,会出现迭代器失效的问题。...可能会有人有疑问,为什么我们不能在原来的那个类里面重载一个返回值为常引用的解引用函数呢?...答案是不可以,因为返回值不同无法构成重载函数,所以这两个不同返回值的函数不能在同一个类里面出现,这也是为什么我们重建了一个类,专门搞了一个返回值为常引用的解引用函数。...不释放当然是正确的,因为结点是属于链表的,释放结点的工作应该交给链表类而不是迭代器类。 所以当内置类型涉及资源申请时,也并不一定就要写析构函数,还需要视情况而定。
emplace_hint() 和 emplace() 生成元素的方式在本质上是一样的,除了必须为前者提供一个指示元素生成位置的迭代器,作为 emplace_hint() 的第一个参数。...不能在 map 容器中保存重复的键,但是可以将键关联到封装了多个名言的对象上。...end() 函数,就不能在 for 循环中使用 const 类型的循环变量: for (const auto& pr : quotations)//Requires const iterators...6删除元素 map 的成员函数 erase() 可以移除键和参数匹配的元素,然后返回所移除元素的个数。...erase(),它可以移除两个迭代器参数所定义范围内的元素。
到这里为止,其实我们还是很疑惑,这个基类啥也没干啊,它有什么作用呢,事实上,对于形如vector vec;这样的声明,vector其实就是调用了这个基类的无参构造,它就是什么也没干,此时也并没有申请动态内存...2. vector从最后面插入元素时发生了什么 2.1 对空vector插入一个元素 上一小节说到,如果vector在构造的时候指定容器大小,那么声明时就会申请动态内存,但如果构造是默认构造,并不会申请动态内存...根据以上逻辑,也就是说,对一个无空间的vector插入一个元素实际上是会先申请1个元素的空间,并把这个元素插入到vector。...什么类型不可以作为vector的模板类型 对于vector模板特化类型,因为在vector的实现过程中,变量会经常被拷贝或者赋值,所以vector的模板类型应该具有公有的拷贝构造函数和重载的赋值操作符函数...什么情况下vector的迭代器会失效 第一是在vector容器中间根据指定迭代器删除元素,也就是调用erase函数,此时因为当前位置会被后面的元素覆盖,所以该指定迭代器会失效,不过此时可以通过erase
(当然,前边讲的拷贝的工作方式,以前也是没有去注意到的) 分割问题暗示了把一个派生类对象插入基类对象的容器几乎总是错的。 那,对于这种拷贝的工作方式,有没有什么好的对抗办法呢?...当容器的一个元素被删时,指向那个元素的所有迭代器都失效了。当c.erase(i)返回时,i已经失效。那对于这个循环是个坏消息,因为在erase返回后,i通过for循环的++i部分自增。...为了避免这个问题,我们必须保证在调用erase之前就得到了c中下一元素的迭代器。...else{ ++i; // 对于好的值,只增加i } } 这种调用erase的解决方法可以工作,因为表达式 i++ 的值是 i 的旧值,但作为副作用,i增加了。...事实上不是这样!“删除的”值完全不必再存在于v中了。 remove并没有改变区间中元素的顺序,所以不会把所有“删除的”元素放在结尾,并安排所有“不删除的”值在开头。
中的功能, STL 可以很大程度上减轻你的工作量,并且内置的异常处理可以让你更清楚的看到你所犯下的错误。...同样所有支持访问所有元素类模板都有自己的迭代器。...的运算符,利用 (vector 变量 )[index] 可以访问和修改第 index 处的元素 添加函数 ◦ void push_back (const T& x): 向量尾部增加一个元素...x ◦ iterator insert(iterator it,const T& x): 向量中迭代器指向元素前增加一个元素 x 删除函数 ◦ iterator erase(iterator...,但是从底层实现上来看,他本质是一个双向链表,不支持随机去访问当中的元素,但是在插入,删除元素的时间复杂度上远低于 vector 类模板 ◦ 常用函数与 vector 当中部分相似或相等,这里不逐一介绍
,参数化了所指向的对象的类型 实例:当你用一个vector结构完成设计时,你总想着泛化容器的不同,想着后面是否可以改成deque或者list等东西代替,善意的泛化,却造成麻烦 结论:写既要和序列容器又要和关联容器一起工作的代码并没有什么意义...,因为很多成员函数只存在其中一类容器中,比如,只有序列容器支持 push_front或push_back,只有关联 容器支持 count和lower_bound等等,又如insert或erase在两者表现上却不同...list)都有效,完全替代一个容器的内容 //为什么区间成员函数优先于它们的单元素的替代品 //区间成员函数是一个像 STL 算法的成员函数,使用两个迭代器参数来指定元素的一个区间来进行某个操作 //...} //如果避免这种问题:必须保证在调用 erase之前就得到了c中下一个元素得迭代器,因此在 i 上使用后置递增 for(std::set::iterator i = caaaa.begin...1,allocator与类绑定,因为allocator是一个泛型类 2,allocate()申请指定的空间,只分配空间,不构造对象,返回第一个元素的起始地址 3,construct()构造对象,其参数是可变参数
STL---vector 一、vector 的介绍 vector 是表示可变大小数组的序列容器。 就像数组一样,vector 也采用的连续存储空间来存储元素。...也就是意味着可以采用下标对 vector 的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自 动处理。...本质讲,vector 使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小。为了增加存储空间,其做法是,分配一个新的数组,然后将全部元素移到这个数组。...就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector 并不会每次都重新分配大小。...,所以我们在缺省值中需要给一个匿名对象;如果是内置类型,它会初始化为 nullptr 或 0,我们以前了解到的是编译器不会对内置类型进行处理,但是匿名对象会对它进行处理;注意在类型前要加 const 因为匿名对象具有常性
容器大小 : 0 ; 容器容量 : 3 Press any key to continue . . . 3、删除 vector 容器指定 位置 元素 - erase 函数 iterator 迭代器类...的 erase 函数 删除 指定 索引位置 的元素 ; iterator#erase() 函数原型如下 : iterator erase( const_iterator pos ); 该 erase...; 容器容量 : 3 Press any key to continue . . . 4、删除 vector 容器指定 范围 元素 - erase 函数 iterator 迭代器类 的 erase..., const_iterator last ); iterator#erase() 函数 接受两个指向要删除的元素的常量迭代器作为参数 , 返回一个指向被删除元素范围的结束位置之后的迭代器 ; 注意 :...(vec); // 删除容器中第一个和第二个元素 // 此处 for 循环条件中, 不写 it++ , it++ 只能在特定条件下使用 for (vector::iterator
1、vector 连续存储结构,每个元素在内存上是连续的; 支持高效的随机访问和在尾端插入/删除操作,但其他位置的插入/删除操作效率低下; 2、deque 连续存储结构,即其每个元素在内存上也是连续的...这样,deque除了具有vector的所有功能外,还支持高效的首端插入/删除操作。...f、当要存储的是大型负责类对象时,list要优于vector;当然这时候也可以用vector来存储指向对象的指针,同样会取得较高的效率,但是指针的维护非常容易出错,因此不推荐使用。...该函数两个版本返回reverse_iterator或const_reverse_iterator,引用容器第一个元素前面一位 erase 从容器中清除一个或几个元素 clear 清除容器中所有元素...(2) 只能在vector的最后进行push和pop,不能在vector的头进行push和pop。
这样外面的pos确实不是野指针了,但是,这样又不行了: 为什么? 这里是传值返回,返回的是拷贝的临时变量,具有常性,不能传给引用。 那怎么办?...指定位置元素的删除操作–erase 那我们再来实现一下erase: 删除pos位置的元素,那我们就直接挪动后面的元素覆盖就行了,如果后一个的话直接- -_finish就行了。...我们试一下: erase删除pos位置元素后,pos位置之后的元素会往前搬移,没有导致底层空间的改变,理论上讲迭代器不应该会失效,但是:如果pos刚好是最后一个元素,删完之后pos刚好是end的位置...并且这里肯定都要加const的,因为临时变量和匿名对象都具有常性。 那函数内部具体怎么实现呢?...然后只需把每行第一个和最后一个元素初始化为1 ,中间剩余的元素是不是就是它上一行的元素和上一行的前一个元素相加的和啊。
---- STL概述 STL,虽然是一套程序库,但却不仅仅是一套一般印象中的程序库,而是一个具有划时代意义的、有着深厚理论基础的发明。 说是软件组件史上的一大突破,也当之无愧。...仿真函数 行为类似函数,从实现来看是一种重载了operator()的类或模板类。 函数指针可视为狭义上的仿真函数。...} erase() 清除(first,last)中所有元素: 先看图: iterator erase(iterase first,iterase last){ iterator i = copy...() 清除某个位置上的元素: iterator erase(iterator position){ if(position +1 !...相对于Vector,List还有一个优势,就是不论如何的插入和接合操作,都不会造成原有的List迭代器失效。List的删除操作也只有指向那个被删除的元素的迭代器失效,其它迭代器不会受影响。
函数一起使用)merge在相同类型且分别有序的情况下,将 list2 中的元素都搬移到 list1 中,且按大小进行排序 (list2变成空的)sort排序 list 中的元素==(效率低,不推荐)==...可以明显发现,list 和之前的 vector/string 不同,list 是链式结构,在物理空间上是不连续的,所以直接对 list 的原生指针进行操作,比如++操作,是没办法移到下一个 list 元素的位置的...而对于 vector/string 的迭代器,都是原生指针,实现起来非常简单, 因为他们在物理空间上是连续的,也支持随机访问。...我们可以将 list 的原生指针进行封装,变成一个类,再对这个类进行运算符的重载,就能实现意义上的迭代器了! 2....vector、string 的迭代器怎么适配? 这里在取内嵌类型,只有自定义类型才能在里面搞内嵌类型,内嵌类型也是类,typedef也是内嵌类型。如果是一个原生指针呢? 原生指针哪来的内嵌类型?
博主觉得跟之前vector的基本上差不了多少,如果不会看文档用库里面的list的可以去看博主只管关于string和vector的使用。...C++:String类的使用-CSDN博客 C++:Vector的使用-CSDN博客 下面直接介绍List使用中的易错点 2.1 List的迭代器失效问题 我们之前学习vector的时候...虽然看似我们好像用箭头连接起来了,但其实他们空间上是不连续的,那我们对一个节点指针进行加减,就很难说能不能找到下一个节点,更多的是找不到的情况 那我们思考一样,如果我们要搞一个迭代器,我们希望怎么去得到我们的数据呢...因为typedef碰到const的话,就不是简单的字符串替换 实际上你以为的const T* ,在这里变成了T*const ,因为迭代器我们是希望他可以进行++和--的,而我们只是不希望他指向的内容给改变..._cur; } iterator _cur; }; 思考:为什么解引用的是前一个位置的元素???
上次讲了常用的接口:C++初阶:容器(Containers)vector常用接口详解 今天就来进行模拟实现啦 1.基本结构与文件规划 vector.h头文件:包含类的全部(函数的声明与定义) test.cpp...这里假设 T 是一个类或者结构体,那么这个语句会调用 T 的默认构造函数来创建一个临时对象。 const T& x 表示创建一个类型为 T 的常量引用 x。...这里的引用是 T 类型的引用,而且是常量引用,意味着 x 引用的对象是不可修改的。 const T& x = T() 将这个临时对象绑定到常量引用 x 上。...迭代器失效可以大致分为两类: 结构性变化导致的失效:这类失效包括扩容时申请了新空间、插入或删除元素导致元素位置改变等情况。...,erase 函数会返回指向被删除元素之后的元素的迭代器,而不是原先被删除元素的迭代器。
一,前言 在学习string类的时候,我们可能会发现遍历的话下标访问特别香,比迭代器用的舒服,但是下标其实只能是支持连续的空间,他的使用是非常具有局限性的,随着STL学习的深入我们会发现其实迭代器才是大佬...思考:为什么迭代器也要搞个类模板呢? 答:本质上是为了让这个函数更加灵活,可以传不同类型的迭代器来帮助我们初始化!!...2.const T&val=T() T()不是用一次就析构吗,为什么可以用引用 答:T()是一个用一次就析构的匿名对象,其实本质上是因为他没有名字,用T引用val可以充当他的名字,此时用val就相当于用这个匿名对象...思考: 为什么存string类就会崩了?? ...2.3.2 erase的失效 erase 删除 pos 位置元素后,pos 位置之后的元素会往前搬移,没有导致底层空间的改变,理论上讲迭代器不应该会失效,但是:如果 pos 刚好是最后一个元素,删完之后
在实现拷贝构造后,实现赋值重载就比较简单了,利用传值拷贝构造的临时对象即可,然后调用swap类成员函数即可完成自定义类型的赋值工作。为了符合连续赋值含义,我们利用引用来作为返回值。...//1.为什么不用传引用来解决这里的问题呢?...erase删除任意位置代码后,linux下迭代器并没有失效,因为空间还是原来的空间,后序元素往前搬移了,it的位置还是有效的,但是在vs下就会直接报错,所以对于erase之后迭代器是否失效的这一讨论,为了保证程序良好的移植性...这就是if和if else在用法上的区别。 平常在使用时,要根据具体场景恰当选择这两个分支语句中的哪一个,之前我不知道两者区别的时候,就因为使用的场景不恰当,导致出现了很多的bug。...解引用比较麻烦 } size_t size()const//const和非const对象都能调 { return _finish - _start; //左闭右开的差正好就是这个区间内的元素个数,[
一、标准库的vector类型 vector是同一种类型的对象的集合 vector的数据结构很像数组,能非常高效和方便地访问单个元素 vector是一个类模板(class template) vector... using std::vector; vector对象的初始化: vector类定义了好几种构造函数 vector v1; //vector保存类型为T的对象...默认构造函数v1为空 vector v2(v1);// v2是v1的一个副本 vector v3(n, i); //v3包含n个值为i的元素 vector v4(n); //...void resize(size_type n, const T& c = T()); (1)如果n大于容器当前的大小(即size()),则在容器的末尾插入n-size()个初值为c的元素,如果不指定初值...= v.end(); /*++it*/) { if (*it == 3) { it = v.erase(it); // erase返回的是当前删除元素的下一个元素
为什么 C++空类的大小不为 0,不同编译器设置不一样,vs 设置为 1 C++标准指出,不允许一个对象(当然包括类对象)的大小为 0,不同的对象不能具有相同的地址 带有虚函数的 C++类大小不为...key,就将一个具有该 key 和 value 的默认值插入这个 map erase()函数,只能删除内容,不能改变容量大小; erase 成员函数,它删除了 itVect 迭代器指向的元素,并且返回要被删除的...为什么是 1.5 倍 vector 通过一个连续的数组存放元素,如果集合已满,在新增数据的时候,就要分配一块更大的内存,将原来的数据复制过来,释放之前的内存,再插入新增的元素 初始时刻 vector...,所以最好倍增长因子设置为(1,2)之间 向量容器 vector 的成员函数 pop_back()可以删除最后一个元素 而函数 erase()可以删除由一个 iterator 指出的元素,也可以删除一个指定范围的元素...平台原因(移植原因) 不是所有的硬件平台都能访问任意地址上的任意数据的; 某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常 性能原因: 数据结构(尤其是栈)应该尽可能地在自然边界上对齐
领取专属 10元无门槛券
手把手带您无忧上云