
C++
文章平均质量分 92
学习C++基础知识
~yY…s<#>
积土成山,积水成渊
展开
-
关于sprintf、snprintf
总结:snprintf在sprintf的基础上增加了对输出长度的控制,提高了代码的安全性。原创 2024-11-01 13:36:13 · 313 阅读 · 0 评论 -
【C++】智能指针
两个节点的资源没有被释放,因为循环引用的问题。初始化两个节点时,各自的引用计数为1,然后node1的next指向node2,使node2节点引用计数变成2;因为node1->_next = node2和node2->_prev = node1时,weak_ptr的_next和_prev不会增加node1和node2的引用计数,所以只要有引用计数变成0,就能释放资源了。它可以用一个对象管理一份资源,在对象构造时获取资源,对象析构时释放资源,并且在对象的生命周期中始终可以使用资源。这种方法其实也不行。原创 2024-05-19 13:32:07 · 1135 阅读 · 21 评论 -
【C++】异常
实际使用中很多公司都会自定义自己的异常体系进行规范的异常管理,因为一旦有人随意抛异常,就不好了。所以实际中都会定义一套继承的规范体系。这样大家抛出的都是继承的派生类对象,捕获一个基类就可以了。////......_id是编号,_errmsg是具体错误信息。what()函数返回错误信息,记得要加上virtual,形成多态。原创 2024-04-12 20:11:34 · 1180 阅读 · 30 评论 -
【C++】lambda表达式
以上代码虽然可以实现自定义类型中的某个成员的比较规则,但是这样写是不是有些麻烦,每次实现一个algorithm算法,都要重新去写一个类,如果每次比较的逻辑不一样,还要去实现多个类,特别是相同类的命名,这些都给编程者带来了极大的不便。这段代码捕捉列表后面要有小括号和mutable,因为捕捉列表里的a和b是常属性的,带上mutable可以取消常属性,有mutable不管有没有参数都要加上小括号。函数对象,又称为仿函数,即可以像函数一样使用的对象,就是在类中重载了operator()运算符的类对象。原创 2024-04-09 12:40:58 · 2797 阅读 · 12 评论 -
【C++】新的类功能和可变参数模板
empalce系列中的emplace_back函数与push_back函数的功能是相同的,都是尾插数据。只需在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。对于深拷贝类对象,如果插入的是类对象时,两个没有区别;如果插入的是对象的参数,那么emplace系列函数会。对于浅拷贝类对象,如果插入的是类对象时,两个没有区别;如果插入的是对象的参数,那么emplace系列函数会。很明显是不行的,因为模板是编译时解析,for循环是运行时解析参数。原创 2024-04-02 12:38:10 · 683 阅读 · 8 评论 -
【C++】右值引用
引用是给对象取别名,本质是为了减少拷贝。以前我们学习的引用都是左值引用,右值引用是C++11新增的语法,它们的共同点都是给对象取别名。既然如此,有了左值引用,为什么还要有右值引用?右值引用具体是怎样的?以及它有哪些应用场景?接下来,会详细分析~~左值是一个表示数据的表达式,可以是变量名、解引用的指针和前置++。左值可以取地址和赋值,它出现在赋值符号的左边。如果定义的左值被const修饰,那么它就不能被赋值,但是可以取地址。//左值int a = 10;原创 2024-03-31 09:45:17 · 1257 阅读 · 31 评论 -
【C++】哈希之布隆过滤器
一种支持删除的方法:将布隆过滤器中的每个比特位扩展成一个小的计数器,插入元素时给k个计数器(k个哈希函数计算出的哈希地址)加一,删除元素时,给k个计数器减一,通过多占用几倍存储空间的代价来增加删除操作。k为哈希函数的个数,这里有3个哈希函数,m为布隆过滤器的长度,n为插入元素的个数,ln2的大小约为0.69,推导出:4.34 * n = m,简化一下m与n的关系为:5n = m。插入元素时,不同的哈希函数计算出该元素的不同的映射位置,然后将要映射的位置标记为存在,即比特位为1。原创 2024-04-06 15:22:50 · 1193 阅读 · 8 评论 -
【C++】哈希之位图
一个整数等于32个比特位,根据位图的概念,用每个比特位是1还是0来确定一个数到底在不在,1个整数的32个比特位可以用来确定32个数据的存在,所以16G除以32等于0.5G,即512M,这就是开辟的空间大小,是不是节省多了。类的模板是非类型模板参数,传的是数据的大小。一个二进制比特位只有两种状态,要么为0,要么为1,如果某个数据在,则对应映射的比特位为1;每个数都有对应映射的比特位,将这个数除以32找到该数在数组中的位置,取模32找到映射的第几个比特位,1左移前面取模的位数,然后按位或将该比特位设置为1。原创 2024-04-02 21:47:35 · 1251 阅读 · 6 评论 -
【C++】用哈希桶模拟实现unordered_set和unordered_map
顺序结构中(数组)查找一个元素需要遍历整个数组,时间复杂度为O(N);树形结构中(二叉搜索树)查找一个元素,时间复杂度最多为树的高度次logN。可以不经过任何比较,一次直接从表中得到要搜索的元素。构造一种存储结构,通过某种函数使元素的存储位置与它的关键码之间能够建立一一映射的关系,那么在查找时通过该函数可以很快找到该元素。主要有3种操作:插入——根据待插入元素的关键码,以此函数计算出该元素的存储位置并按此位置进行存放查找。原创 2024-03-24 18:22:09 · 1523 阅读 · 27 评论 -
【C++】用红黑树模拟实现set、map
set、map的底层结构是红黑树,它们的函数通过调用红黑树的接口来实现,红黑树一些接口需要通过树形迭代器来实现。set是k模型,map是kv模型,红黑树要不要写两份呢?答案是不需要,只用一份即可,通过仿函数来控制。T _data;,_col(RED){}红黑树有3个指针域,数据域用T来表示,如果是set,那么传过来的是k模型;如果是map,是kv模型。新增的节点的颜色默认是红色(根节点除外)。原创 2024-03-19 20:51:55 · 1155 阅读 · 22 评论 -
【C++】实现红黑树
红黑树也是三叉链结构(左指针、右指针和父亲指针),有一个新的存储位来记录节点的颜色,这里实现的红黑树是kv模型。RED,//红色BLACK//黑色,_kv(kv),_col(RED)//默认的新节点都是红色的{}原创 2024-03-15 21:00:48 · 1305 阅读 · 21 评论 -
【C++】AVL树的插入、旋转
AVL树是高度平衡的二叉搜索树,相比普通的二叉搜索树,它防止了变成单支树的情况。因为AVL树每插入一个新的节点,它都会调整使左右子树的高度差的绝对值不超过1,从而降低了树的高度,提高了搜索效率。左右子树都是AVL树左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1)搜索时间复杂度O(log2nlog_2 nlog2n有平衡因子控制高度差:右子树高度减去左子树高度AVL树是三叉链结构,即左孩子指针、右孩子指针和双亲指针,多了一个双亲指针方便找到上一个节点。原创 2024-03-12 16:23:25 · 1292 阅读 · 16 评论 -
【C++】set、multiset与map、multimap的使用
目录一、关联式容器二、键值对三、树形结构的关联式容器3.1 set3.1.1 模板参数列表3.1.2 构造3.1.3 迭代器3.1.4 容量3.1.5 修改操作3.2 multiset3.3 map3.3.1 模板参数列表3.3.2 构造3.3.3 迭代器3.3.4 容量3.3.5 修改操作3.3.6 operator[]3.4 multimap一、关联式容器谈到关联式容器,先来说说序列式容器,以前学习的vector、list、deque等就是序列式容器,它们的特点是底层为线性序列的数据结构,存储的是元原创 2024-03-03 17:32:06 · 1205 阅读 · 22 评论 -
【C++】二叉搜索树
还有一点,递归的话不需要循环那样得有一个parent来记录上一次的位置,因为从哪里递归下来、返回回去,都是确定好的,即从当前位置往左子树的方向下去,返回就从左子树的位置回去,右边一样的。这里要注意的一点是,因为是在类里写,每个成员函数都有隐藏的this指针,而递归写法是要带参数的,所以这里写中序遍历时,要有一个子函数来递归,后面的递归写法也要这样。删除,即将要删除的节点的值与它的左子树或者右子树中的某个节点的值进行替换,然后再把替换后的节点删除,与其他节点连接。与左为空类似,连接的是Cur的左子树。原创 2024-02-19 13:01:06 · 1232 阅读 · 26 评论 -
【C++】学习多态原理
用基类对象去调用,派生类对象给基类对象是切片,但注意:这过程中有拷贝构造出一个基类的对象,这个基类的对象所对应的虚表是基类的虚表,结果导致拷贝构造的基类对象都去基类对象的虚表中找虚函数,就没有调用派生类对象的虚表中的虚函数了。因为派生类继承基类得到基类的那部分的虚表,虚表里面的虚函数地址是基类的,如果不进行重写,在派生类对象的虚表中找到的虚函数依然是基类的,所以要对基类的虚函数进行重写,虚表中也同时完成了虚函数地址的覆盖,调用时就是派生类的了。注意:同一个类的对象,对应的是同一张虚表。原创 2024-04-05 14:47:10 · 834 阅读 · 7 评论 -
【C++】多态语法概念
概念:在继承关系下的不同类,调用同一个函数,产生不同的行为,叫作多态。图示:定义:必须通过基类的指针或者引用调用虚函数;被调用的函数必须是虚函数。类里的函数的返回类型前加上virtual就是虚函数,子类继承父类的虚函数叫作重写,重写的是虚函数的实现,该虚函数的返回类型、函数名、参数列表都要与父类相同(有两个特例,后面再谈)。public:cout << "全价" << endl;public:cout << "半价" << endl;原创 2024-02-11 12:51:42 · 495 阅读 · 6 评论 -
【C++】继承
以前我们的接触过函数复用,而继承就是一种类复用,减少代码的重复性。继承可以在原有类的基础上扩展新的功能,产生新的类叫派生类或子类,原有类叫基类或父类。比如说学生类和老师类,它们共同的成员变量有名字和年龄,这时就可以写个Person类来处理公共的成员变量,不需要学生类和老师类自己再写名字和年龄的成员变量,只要写自己的独有的那部分即可。原创 2024-02-04 12:44:11 · 1502 阅读 · 23 评论 -
【C++】list的模拟实现
list是带头双向循环链表,与vector的底层结构不一样,vector是连续的空间,list的每个节点是独立的空间。struct ListNode//节点类struct ListIterator//正向迭代器类struct ReverseIterator//反向迭代器类class list//模拟实现list类//获取第一个节点数据T& front()//获取最后一个节点数据T& back()原创 2024-01-25 19:49:06 · 1537 阅读 · 20 评论 -
【C++】list的使用
但是会出现以上的情况,因为pos指向元素为3的节点,第一次插入是3的前面没有问题,但是第二次插入时pos还是指向元素3,所以插入999还是在元素3的前面插入。返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的reverse_iterator,即begin位置。因为第一次删除pos位置的节点,该节点已经不存在了,第二次删除还是使用上一次的pos,所以会报错。list不需要扩容,它的每个节点是独立的一块空间,根据需求来进行新增节点或者删除节点。原创 2024-01-23 23:03:07 · 1200 阅读 · 7 评论 -
【C++】stack、queue的使用及模拟实现
stack作为容器适配器,它的底层可以复用其他的容器,例如vector、list、deque,默认的情况下使用的是deque,deque兼具vector和list在实现上的功能,只是有些在效率上会有所差异。queue也是一种容器适配器,特点是先进先出,在一端插入元素,另一端删除或者获取元素。stack是一种容器适配器,它的特点是后进先出,只能在容器的一端进行插入和删除操作。queue的模拟实现与stack同理。原创 2024-01-24 23:24:44 · 503 阅读 · 11 评论 -
【C++】vector的使用及模拟实现
vector是一个可变大小数组的容器,与数组一样,vector也是一块连续的空间,可以像数组一样对元素进行高效的遍历访问,但是普通数组的大小是不变的,vector可以改变自身大小。vector是采用动态分配数组来存储数据,即插入新元素时要改变存储空间大小,往往要分配一个新的数组,然后把原来数组的元素转移到新的空间里。vector的尾插尾删效率高,中间插入和删除效率较低。原创 2024-01-16 19:37:26 · 1397 阅读 · 29 评论 -
【C++初阶】学习string类的模拟实现
前面已经学习了string类的用法,这篇文章将更深入的学习string类,了解string类的底层是怎么实现的。当然,这里只是模拟一些常用的,不常用的可以看文档学习。原创 2023-12-20 19:06:43 · 2616 阅读 · 26 评论 -
【C++初阶】STL之学习string的用法
STL是C++的标准模板库,里面包含了许多算法和数据结构,例如我们熟悉的顺序表、链表、栈和队列以及一些常见的算法等等,编程者想使用这些就可以直接从库中调用,不必再自己造轮子了。下面为STL内容的一张图:接下来,我们要学习STL中的string。string 是C++的一个类模板,字符串的类模板。要定义一个对象为字符串,就可以用string类型,说明它是一个字符串,相当于字符数组。原创 2023-11-24 20:34:10 · 1358 阅读 · 43 评论 -
【C++初阶】内存管理 && 初识模板
当对象是自定义类型时,malloc不方便自定义类型初始化,因为malloc只会开辟空间,free只会释放空间。原创 2023-11-16 13:31:45 · 398 阅读 · 31 评论 -
【C++初阶】类与对象(三)
这个引用成员变量,那么定义的地方在哪?就在初始化列表。2️⃣const成员变量与引用也是一样的,在私有的区域里只是声明,要定义的话必须在初始化列表。3️⃣上篇文章使用队列类的时候我们没有写队列类的构造函数,内置类型声明有缺省值使用缺省值,没有是随机值;自定义类型成员变量让编译器自动调用它的默认构造。复习下什么是默认构造:1.我们不显示写构造函数编译器默认自动生成的2.没有传参的3.全缺省的。原创 2023-11-12 21:16:02 · 444 阅读 · 33 评论 -
【C++初阶】类与对象(二)
构造函数——初始化析构函数——清理拷贝构造函数——使用同类对象初始化创建对象赋值运算符重载——一个对象赋值给另一个对象const成员函数——修饰this指针取地址重载——获取对象地址默认的意思是我们自己不写编译器自动生成,当然我们也可以自己写。1、写,应该怎样实现;2、不写,是否符合要求。原创 2023-11-03 21:01:22 · 491 阅读 · 31 评论 -
【C++初阶】类与对象(一)
/// 类体:由成员函数和成员变量组成//// 一定要注意后面的分号,与C语言的结构体同class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类的定义有两种写法,一种是声明和定义全部写在类里,另一种是分文件声明和定义分离,在做项目的时候或者代码规模较大以后者居多。int top;原创 2023-10-23 20:26:44 · 345 阅读 · 27 评论 -
【C++初阶】小白入门C++
从本篇文章开始就正式进入C++的学习了,C++在C语言的基础上增加了面向对象的思想,还有许多库,在使用上相比C语言大大提高了效率,同时在语法上也填上C语言的坑。本篇文章是介绍C++入门的基础语法知识,接下来我们一起往下看吧~在C++中,允许同一作用域中出现名字相同但类型/参数个数/类型顺序不同的函数,这类函数叫做重载函数。常用来解决功能类似数据类型不同的问题。return 0;Add(6);原创 2023-10-21 14:26:11 · 656 阅读 · 21 评论