当前位置: 首页 > news >正文

网站保姆-源码下载网站建设数据库的选择

网站保姆-源码下载,网站建设数据库的选择,网站免费空间,域名注册的流程目录 vector中的三个重要迭代器 默认成员函数 构造函数(无参构造) 构造函数(函数模板) 构造函数(带有默认参数) size_t int 拷贝构造函数 赋值重载 析构函数 迭代器相关函数 begin和end 容量和大小相关函数 size capacity resize 修改容器内容相关函数 reser… 目录 vector中的三个重要迭代器 默认成员函数 构造函数(无参构造) 构造函数(函数模板) 构造函数(带有默认参数) size_t int 拷贝构造函数 赋值重载 析构函数 迭代器相关函数 begin和end 容量和大小相关函数 size capacity resize 修改容器内容相关函数 reserve push_back insert  情况一pos迭代器失效  情况二:  insert之后迭代器失效 erase 情况三vs2019进行强制检查erase以后认为it失效了不能访问访问就报错 访问容器相关函数 operator[ ] const operator[ ] 前言 个人博客Dream_Chaser 博客专栏C 本篇内容vector类通用函数的模拟实现 vector中的三个重要迭代器 在vector当中有三个成员变量_start、_finish、_endofstorage。 _start指向容器的头_finish指向容器当中有效数据的尾_endofstorage指向整个容器的尾。 默认成员函数 构造函数(无参构造) vector():_start(nullptr),_finish(nullptr),_endofstorage(nullptr) {} 我们可以在函数声明处给上缺省值那么就不用在初始化列表中再初始化了 class vector { private:iterator _start nullptr;iterator _finish nullptr;iterator _endofstorage nullptr; }; 构造函数(函数模板) 这是一个vector构造函数模板它接收两个迭代器first和last作为参数用来创建一个新vector并拷贝first到last范围内的所有元素到这个新vector里。具体操作是遍历这个区间逐个将元素添加到vector末尾。 templateclass InputIterator vector(InputIterator first, InputIterator last) {while (first ! last){push_back(*first);first;} } 构造函数(带有默认参数) size_t 定义了一个向量vector的构造函数它接受两个参数元素数量n和一个可选的默认值val。函数首先预留足够的容量来存储n个元素然后通过一个循环将val这个值添加到向量中 n次。 如果未提供val则默认添加该类型默认值如整数类型的0。这样实现了快速构造一个特定大小且元素具有相同值或默认值的向量对象。 vector(size_t n, const T val T()) {reserve(n);for (size_t i 0; i n; i){push_back(val);} } int 唯一不同在于第一个函数接受size_t n作为参数而第二个函数接受int n这种差异主要体现在参数类型的差别上建议使用size_t更符合C标准库容器的惯例因为它是一种无符号类型更适合表示容器的大小能避免负数引发的错误。 vector(int n, const T val T()) {reserve(n);for (int i 0; i n ; i){push_back(val);} } 拷贝构造函数 定义了一个C向量(vector)类的拷贝构造函数其功能是创建一个新的vector对象作为现有vector对象的完整副本。 为新vector预分配与被拷贝vector相同的能力的内存空间以优化存储管理。        随后通过遍历被拷贝vector的所有元素并逐个将这些元素通过拷贝构造的方式添加到新vector中实现了元素的深复制确保了两个vector之间数据的独立性。         简而言之这是一个实现深度拷贝的拷贝构造函数用于高效地创建vector对象的独立复制品。 // 定义一个拷贝构造函数接受一个const引用类型的vectorT参数v vector(const vectorT v) {// 首先为新创建的vector预分配足够的内存来容纳v中的所有元素// 通过调用reserve函数设置容量至少为v.capacity()reserve(v.capacity());// 然后遍历v中的每一个元素for(auto e : v){// 对于v中的每一个元素e使用push_back成员函数将其添加到当前vector对象中// 这里会自动调用T类型的拷贝构造函数来复制元素epush_back(e);} } 赋值重载 此 swap 函数通过C标准库的 std::swap 高效地交换两个 vector 实例的内部指针实现资源的快速互换。 void swap(vectorT v) {std::swap(_start, v._start); // 交换起始指针std::swap(_finish, v._finish); // 交换结束指针std::swap(_endofstorage, v._endofstorage); // 交换容量指针 } 简单来说就是重写了操作符的行为让它可以用于自定义类型在这里是vectorT。这个函数首先创建了一个临时的vectorT对象tmp通过拷贝构造初始化为右边要赋值过来的vectorT。 然后它使用swap成员函数迅速将当前vectorT的资源包括内存指针等与临时对象tmp交换这一步骤隐含了原vectorT资源的清理。最后函数返回当前对象的引用以便支持连续赋值如a b c;。这种方法提高了效率并确保了正确管理内存。 vectorT operator(vectorT tmp) {swap(tmp); // 使用swap成员函数交换临时对象tmp与当前对象的状态return *this; // 返回当前对象的引用支持链式赋值 } 析构函数 核心任务是清理并释放由vector实例所占用的资源。具体而言它首先通过delete[] _start;释放了存储元素的数组内存防止内存泄漏。 将与该vector实例相关的三个关键指针——_start、_finish和_endofstorage——全部赋予nullptr值不仅提高了程序的安全性避免了悬挂指针的潜在风险还便于开发人员在调试过程中识别出这些资源已被妥善清理且对象处于待销毁的最终状态。 // 定义vector类的析构函数 ~vector() {// 释放_start指针指向的动态分配内存这里是存储vector元素的数组delete[] _start;// 将_start、_finish和_endofstorage指针全部置为nullptr// 目的是// 1. 避免野指针提高程序运行时的安全性// 2. 方便调试 nullptr表明这些资源已被释放// 3. 有助于指示该vector对象已完全清理准备安全销毁_start _finish _endofstorage nullptr; } 迭代器相关函数 vector当中的迭代器实际上就是容器当中所存储数据类型的指针。 // 定义一个迭代器类型其中T代表某种数据类型iterator是一个指向该类型T的指针。 typedef T* iterator;// 定义一个常量迭代器类型它是一个指向常量的指针用于遍历不可修改的数据。 // 这意味着通过const_iterator访问的数据不能被修改保证了数据的安全性。 typedef const T* const_iterator; begin和end 定义begin()函数返回指向容器起始元素的迭代器 定义end()函数返回指向容器最后一个元素之后位置的迭代器 iterator begin() {return _start; // 返回_start指针它是容器的第一个元素的地址 }iterator end() {return _finish; // 返回_finish指针它是容器结束位置的下一位置 } 定义const版本的begin()函数和end()函数用于不可修改的迭代访问(只读不可写) const_iterator begin() const {return _start; // 返回指向容器起始的常量迭代器保证元素不可被修改 }const_iterator end() const {return _finish; // 返回指向容器结束位置之后的常量迭代器// 保证迭代访问过程中元素不可被修改 } 容量和大小相关函数 size 返回vector中元素的个数, 这是vector中保存的实际对象的数量不一定等于它的存储容量。 size_t size() {return _finish - _start; } capacity 返回当前为vector分配的存储空间大小以元素表示 size_t capacity() const {return _endofstorage - _start; } resize nsize容器的内容会被缩减至前n个元素移除超出的部分并销毁这些元素。 sizencapacity容器的内容会通过在末尾插入足够多的元素来扩展以达到n的大小。如果指定了val值新插入的元素将初始化为val的副本如果没有指定val默认情况下它们将被赋予默认值初始化(空值)。 ncapacity那么会自动重新分配已分配的存储空间。 // 该函数用于重新调整容器的大小并可选地用指定值填充新增的元素 void resize(size_t n, const T val T()) {// 如果请求的新大小小于等于当前容器的大小则只需调整_finish指针即可无需增删元素if (n size()){_finish _start n; // 将_finish指针前移使容器表现为缩小}else{// 如果请求的新大小大于当前容器的容量首先确保容量足够大reserve(n); // 调整容器的容量至少为n// 然后使用指定的值val填充从当前位置到新大小之间的所有元素while (_finish _start n) // 循环直到到达新的结束位置{*_finish val; // 将val赋值给当前位置的元素_finish; // 移动到下一个位置}} } 修改容器内容相关函数 reserve 规则 要求vector容器容量至少足以容纳n个元素。 如果n大于当前的vector容量则该函数使容器重新分配其存储空间将其容量增加到n(或更大)。 在所有其他情况下函数调用不会导致重新分配vector容量也不会受到影响。 这个函数对vector的大小没有影响也不能改变vector的元素: 不影响元素数量不改变元素内容 拷贝的部分为什么不能使用memcpy vector容器存储的是 string 对象每个 string 对象内部管理着一块动态分配的字符数组。如果直接使用 memcpy 来复制 string 对象只是浅拷贝了指针和一些成员变量源对象和复制后的对象会共享同一块字符数组。当源 vector 销毁时这块字符数组会被释放导致新 vector 中的字符串变为悬挂指针访问时会引发未定义行为。 那为什么要用这个编译器默认的赋值重载 这里强调一个事情就是说 对于内置类型由于其直接存储值的特性复制总是“深拷贝”(直接存储其值没有指针或间接管理的资源)。而对于自定义类型尤其是包含动态分配资源的类型需要明确区分深拷贝和浅拷贝并根据需要实现深拷贝以保证数据的独立性和正确性。 // 该函数用于重新分配容器的内存确保至少能容纳n个元素而不必重新分配 void reserve(size_t n) {// 检查请求的容量是否大于当前容量if (n capacity()){// 分配一个新的内存块大小为n个T类型的元素T* tmp new T[n];// 记录当前容器中元素的数量size_t sz size();// 如果原容器已有数据if (_start){// 将原容器的数据复制到新分配的内存中for (size_t i 0; i sz; i){tmp[i] _start[i];}// 释放原容器占用的内存delete[] _start;}// 更新指针//使得_start指向新内存的开始//_finish指向已有的元素末尾//_endofstorage指向新内存的末尾_start tmp;_finish _start sz;_endofstorage _start n;} } push_back 在vector当前最后一个元素的末尾添加一个新元素。val的内容被复制(或移动)到新元素中。 void push_back(const T x) {//方法一/*if (_finish _endofstorage){reserve(capacity() 0 ? 4 : capacity() * 2);}*_finish x;_finish;*///直接复用:insert(end(),x); } insert  当 _finish _endofstorage  说明该容器需要扩容在此过程中会引发一些bug。 调试过后发现pos指向的内容变为随机值 从上述示例中引出我们迭代器失效的例子 情况一pos迭代器失效  扩容后pos失效了失效原因:扩容导致原来的迭代器还指向旧的空间 解决办法更新pos // 在指定迭代器位置pos前插入一个值为x的元素 void insert(iterator pos, const T x) {// 断言检查确保pos位于_start和_finish之间assert(pos _start);assert(pos _finish);// 如果 Finish 指针已达到存储空间末端进行扩容if (_finish _endofstorage){// 计算当前位置距离_start的距离用于扩容后重新定位possize_t len pos - _start;// 扩容逻辑初始为空时至少分配4个单位空间否则加倍当前容量reserve(capacity() 0 ? 4 : capacity() * 2);// 扩容后根据之前计算的偏移量重新定位pospos _start len;}// 从_finish指针所指位置开始容器尾部向后移动所有元素为新元素腾出空间iterator end _finish - 1;while (end pos){*(end 1) *end; // 每个元素向后移动一位--end;}// 在腾出的位置插入新元素x*pos x;// 更新_finish指针表示容器元素数量增加_finish; } 情况二:  insert之后迭代器失效 怎么避免呢 erase 情况三vs2019进行强制检查erase以后认为it失效了不能访问访问就报错 验证erase迭代器失效 用示例 1 2 3 4 5 验证的时候发现没有出现问题但是用 1 2 3 4 5 6 验证则会出现错误 而且发现用这个验证的时候2 2 3 4 5并没有把所有的偶数都删去。 验证 1 2 3 4 5 和 2 2 3 4 5 当验证 1 2 3 4  5  6时 当循环中删除元素后直接使用it如果该元素正好是最后一个满足删除条件的元素那么在删除后it会指向容器的end()此时再执行it就会越界尤其是在开启了迭代器调试检查的编译器环境下如VS2019的迭代器检查功能会直接报告错误。 不能直接it如果没有删除元素才进行迭代器的自增 void test_vector5(){//1 2 3 4 5 //1 2 3 4 5 6//2 2 3 4 5std::vectorint v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);v.push_back(6);for (auto e : v){cout e ;}cout endl;auto it v.begin();while (it ! v.end()){//vs2019进行强制检查erase以后任务it失效了不能访问访问就报错if (*it % 2 0){it v.erase(it);}else{it;}}for (auto e : v){cout e ;}cout endl;} 访问容器相关函数 operator[ ] 非 const版本 的 operator[ ] 允许对容器内的元素进行读写操作。 这个函数被调用时它会直接返回 _start[pos] 即容器起始地址偏移pos位置的元素的引用。由于返回的是引用所以可以通过这个返回值来修改容器内的元素。 // 非const版本的下标访问运算符 T operator[](size_t pos) {// 断言检查传入的索引pos是否小于当前容器的大小确保索引合法assert(pos size());// 返回指定位置pos的元素的引用允许用户修改该元素return _start[pos]; } const operator[ ] const 版本的 operator[ ] 主要用于 const对象 或者通过 const引用访问容器时。它返回元素的常量引用意味着通过这种方式访问到的元素是只读的不能被修改从而保证了容器在声明为const时的数据完整性。 // const版本的下标访问运算符 const T operator[](size_t pos) const {// 同样进行索引合法性检查assert(pos size());// 返回指定位置pos的元素的常量引用保证该元素不可被修改return _start[pos]; } 本文修改次数0 更新时间2024年 5 月 10 日
http://www.zqtcl.cn/news/605563/

相关文章:

  • 设计模板图热狗网站关键词优化
  • 无锡网站开发公司重庆网站有哪些
  • 做网站找什么公司工作网站开发思维导图内容
  • 有人知道做网站吗?wordpress多站点cdn
  • 网站风格特点大型外包公司有哪些
  • 如何网站seo用asp做网站有哪控件
  • 网站建设需要哪些成本wordpress商城建站教程
  • 做网络的网站很重要吗网站认证费用
  • flash网站项目背景网页截图快捷键可拉动
  • 郑州企业建设网站北京企业网站模板建站开发
  • 宣传旅游网站建设的观点是什么公众号怎么推广和引流
  • 企业网站制作多少钱山西网络营销方案
  • 焦作住房和城乡建设局网站旅行网站模板
  • 男做基视频网站国家重点高新技术企业名单
  • 公司官方网站开发网站建设电子商务
  • seo网站优化系统搜索引擎优化排名案例
  • 郑州网站建设工作室网站建设全流程 知乎
  • 如何利用源码做网站外贸网站制作推广
  • 国内做网站哪家公司好免费查找资料的网站
  • 自己做的网站百度搜不到搭建网站seo
  • 奇墙网站建设高端网站建设公司联系电话
  • 宁波那家公司做网站好中企动力科技股份有限公司招聘
  • 水果网站推广网站首页静态好还是动态好
  • iis网站属性小程序源码无需服务器
  • 景区网站建设材料代运营有哪些套路坑
  • 六安电商网站建设哪家好有关做美食的网站
  • 卸载wordpress插件网店seo关键词
  • 金山网站制作赤城seo网站优化排名
  • 提供坪山网站建设深圳商城网站哪家做的好
  • 有什么网站可以帮人做模具吗热搜榜百度一下你就知道