![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C++
文章平均质量分 91
头发没有代码多
这个作者很懒,什么都没留下…
展开
-
C++——类型转换
父类指针有可能指向父类,也有可能指向子类,这里fun函数形参pa可能指向父类也可能指向子类,如果pa指向父类,我们将其转换成子类此时会有风险,父类只有_a,父类指针只能访问4个字节空间,子类还有_b,若转为子类,此时指针就会越界,指针越界后就能访问_b,但是对于父类来说_b不属于自己,所以会有隐患。若是父类指针,该指针若指向子类,该指针会受到父类类型的束缚,该指针只能访问到父类的一部分,不能访问子类,但是可以转回子类,这种转换就可以用dynamic_cast。用于意义相近的类型。原创 2023-03-06 08:59:45 · 718 阅读 · 16 评论 -
C++——特殊类设计
这样红框里创建对象就会报错,我们就只能通过第三种方式在堆上创建对象,因为第三个创建对象的方式不会调用析构,但也存在一个问题,该对象无法释放,如果delete ptr编译器就会报错。2.由于在自己的对象内部,不能创建自己的对象,但我们可以创建自己的指针或静态自己的对象,也可以创建一个静态的指针对象,这里我们创建一个静态的对象。但这里又会报错,所以不能禁用拷贝构造,这种情况整体不容易处理,因为CreateObj里面创建了局部对象,必须传值返回,不能引用返回(因为会被销毁)仗时都是人拼人的对砍。原创 2023-03-03 10:10:37 · 343 阅读 · 0 评论 -
C++——智能指针1
next析构右边就释放(delete),prev析构左边就释放(delete),_next在左边,左边的节点被delete时调用析构函数,_next作为成员才会析构,而要释放左边的节点,_prev就得先释放,释放_prev就要先释放右边的节点,右边的节点是否释放又取决于_next,所以俩边互相克制。当释放的时候把ptr强转为char*然后-4,ptr此时指向记录次数这块空间,然后转为int*,再解引用就可获得析构次数,之后开始调用析构函数,free的时候,free的是ptr-4这个位置就是开头的位置。原创 2023-03-01 15:20:33 · 412 阅读 · 2 评论 -
C++——异常
实际使用中很多公司都会自定义自己的异常体系进行规范的异常管理,因为一个项目中如果大家随意抛异常,那么外层的调用者基本就没办法玩了,所以实际中都会定义一套继承的规范体系。这样大家抛出的都是继承的派生类对象,捕获一个基类就可以了// 服务器开发中通常使用的异常继承体系public:, _id(id){}return _id;原创 2023-02-26 14:56:12 · 583 阅读 · 11 评论 -
C++——C++11第三篇
callable的参数。其中,newCallable本身是一个可调用对象,arg_list是一个逗号分隔的参数列表,对应给定的。std::bind函数定义在头文件中,是一个函数模板,它就像一个函数包装器(适配器),接受一个可。arg_list中的参数可能包含形如_n的名字,其中n是一个整数,这些参数是“占位符”,表示。可以将bind函数看作是一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对。言,我们用它可以把一个原本接收N个参数的函数fn,通过绑定一些参数,返回一个接收M个(M。原创 2023-02-22 10:28:17 · 522 阅读 · 10 评论 -
C++——C++11第二篇
不能互相赋值是因为这是俩个lambda,俩个lambda的uuid(上面汇编)不一样,相当于这俩个lambda属于俩个类型,但是可以将lambda表达式赋给函数指针。(printarg(arg2),0), (printarg(arg3),0), etc... ),最终会创建一个元素值都为0的数组int arr[sizeof...表,通过初始化列表来初始化一个变长数组, {(printarg(args), 0)...}将会展开成((printarg(arg1),0),原创 2023-02-20 15:12:22 · 620 阅读 · 12 评论 -
C++——C++11 第一篇
左值引用总结:我们可以获取它的地址+可以对它赋值,左值可以出现赋值符号的左边,右值不能出现在赋值符号左边。1. 左值引用只能引用左值,不能引用右值。2. 但是const左值引用既可引用左值,也可引用右值右值引用总结:右值可以出现在赋值符号的右边,但是不能出现出现在赋值符号的左边,右值不能取地址。1. 右值引用只能右值,不能引用左值。2. 但是右值引用可以move以后的左值。原创 2023-02-18 09:14:00 · 731 阅读 · 20 评论 -
C++——哈希4|布隆过滤器
理论而言,一个值映射的位越多,误判冲突的概率就越低,但如果映射过多,空间消耗就会增大。相同的query,一定进入了相同编号的小文件,因为是同哈希函数转出来的然后对这个值取模,一系列操作都一样,只不过是放到了不同的文件中,虽然文件不同但编号相同。这里的比例越大,开的空间越多,误判率就会降低。对于库中的布隆过滤器,若开的空间过大,会导致栈溢出,我们可以把空间转移到堆上去,以下是转移到堆上的代码。布隆过滤器存在误判,如这里如果美团不存在,而B站存在,此时美团的位置被B站占据,有可能会误判为美团此时存在。原创 2023-02-16 09:11:22 · 905 阅读 · 29 评论 -
C++——哈希3|位图
找交集,使用俩个位图,第一个集合对应第一个位图,第二个集合对应第二个位图,如果既在位图1又在位图2,则是交集,或者俩个位图进行与,映射位都是1的就是交集。这里用搜索树和哈希表都不行,搜索树还有left,right,colour有额外空间,哈希表有next指针消耗,这俩种方式都会消耗空间导致内存中存不下。走到8的时候,第二个char显示16进制的1,说明8是第二个char的第一个比特位,是全体的第8个比特位。相同,可能在某些位上分布比较均匀,每种符号出现的机会均等,在某些位上分布不均匀只。原创 2023-02-14 14:17:30 · 726 阅读 · 23 评论 -
C++——哈希2|哈希封装
通过哈希实现unorderedmap和unorderedset,我们把哈希表模板参数这里改为T,哈希表第二个的模板参数对于Map是pair,对于Set是K。set要求能比较大小,要求支持小于比较,比较的时候换一下参数顺序即可。如果不支持比较大小,显示提供比较的仿函数即可。我们在比较数据的时候把这里直接写成了==,这种写法有问题,若是Date*的俩个变量做比较,则比不出来。对于map要使用[],需要修改Insert ,如果新插入,就使用新插入节点构造的迭代器。这块的仿函数也去掉,套在上一层。原创 2023-02-07 15:18:16 · 962 阅读 · 6 评论 -
C++——哈希
这里插入不能像前面那样复用Insert,因为会创建新节点,而且释放旧表又要写析构函数,比较麻烦,我们可以直接将旧表的桶搬下来,给新表使用,这里新表不手动释放原因,新表是一个局部变量,除了作用域后会空间会被释放。若有这样一组值,线性探测在某个位置冲突很多的情况下,会互相占用,导致一大片出现冲突,如这里下标为2的位置被占用,2只能去占另外的位置,为了解决这种问题,有种解决方式叫二次探测。一次探测是每次+i,二次探测是每次加i²,是相对于其实位置每次加i²,i开始是1,若每次计算完,那个地方有元素,则i变为2,原创 2023-02-02 13:25:40 · 700 阅读 · 3 评论 -
C++——map和set封装实现
Insert插入数据的时候要比较数据的大小选择合适的位置插入,但这里data是T类型,对于set可直接比较,而map传过来的是pair,如果比较pair就要比较first和second,这种不满足我们的需求,因为比较的时候既要满足set也要满足Map.第二句话理解,这里7访问完,父亲是6,7是6右子树,更新cur,parent,8是parent,6是cur,cur不是parent右子树。begin是找最左边的节点,这里的_root是红黑树的根节点,end是最后一个节点的下一个位置就是空。原创 2023-02-01 09:54:07 · 840 阅读 · 22 评论 -
C++——map|set2
pair有俩个成员一个是first,一个是second由于pair有俩个模板参数,第一个是first,一个是secondmap的insert参数类型是valud_type,value_type就是pairpair的key_type对应map的第一个模板参数Key,也就是pair的firstmapped_type对应map的第二个模板参数T,也就是pair的second这里的string就是第一个模板参数相当于pair的first,int是第二个模板参数相当于pair的second统计出现的次数。原创 2023-01-30 12:41:07 · 614 阅读 · 9 评论 -
C++——map|set介绍
这样会报错是因为pair不支持流插入, 这里解引用要返回值,但是不支持返回俩个值,因为是kv模型,这样不会报错,因为pair有俩个值一个是first,一个是second,注意头文件string。关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是结构的键值对,在数据检索时比序列式容器效率更高。这种插入会失败,因为已经由string和字符串配对了。2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。原创 2023-01-10 10:17:07 · 1172 阅读 · 8 评论 -
C++——二叉树OJ|二叉树非递归遍历
思路:遍历内容存在数组中,用栈来进行辅助,先遍历左树,每遍历一个节点,就把该节点的地址放入栈中,把节点的值放入数组中(也就以为着根和左节点都放入里面了),之后左树为空,栈顶是最左边而且下面树的根,之后访问右节点,并把根弹出栈。原创 2023-01-08 09:28:27 · 331 阅读 · 18 评论 -
C++——二叉树OJ
最后要返回链表头部,根据根节点往左边找即可找到头部,prev要用引用,是因为递归返回上一层的时候要把确定新的prev的位置,不然prev在第一层是空,第二层是6,当第二成返回第一层时,cur->left=prev,此时应该是10->6,而这里不加引用就是10->nulllptr。使用一个栈解决,如果不是我们要找的节点就入栈,如这里要找6,4把往6这条路走的节点都入栈。这里找4,先找左数3,5,6 6的左右子树为空,就说明没找到4,把6出栈。由于是中序遍历,cur走到6之后会走到8,让8的left指向6。原创 2023-01-05 09:50:45 · 812 阅读 · 21 评论 -
C++——AVL树
2、更新后,parent->bf== 1 or -1,说明parent插入前的平衡因子是0, 说明左右子树高度相等,插入后有一边高,parent高度变了,需要继续往上更新。4、 更新后,parent->bf== 2 or -2, 说明parent插入前的平衡因子是1 or-1, 已经平衡临界值,插入变成2 or -2, 打破平衡,5、更新后,parent->bf> 2 or < -2的值,不可能,如果存在,则说明插入前就不是AVL树,需要去检查之前操作的问题。新增在左,parent-> bf--;原创 2022-12-13 08:37:33 · 329 阅读 · 30 评论 -
C++——IO流
在C语言中,如果想要将一个整形变量的数据转化为字符串格式,如何去做?1. 使用itoa()函数2. 使用sprintf()函数但是两个函数在转化时,都得需要先给出保存结果的空间,那空间要给多大呢,就不太好界定,而且转化格式不匹配时,可能还会得到错误的结果甚至程序崩溃。在C++中,可以使用stringstream类对象来避开此问题。头文件#Include在程序中如果想要使用stringstream,必须要包含头文件。原创 2023-03-08 18:13:13 · 854 阅读 · 13 评论 -
C++——红黑树
红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。最长路径不超过最短路径的二倍红黑树的性质:1. 每个结点不是红色就是黑色2.根节点是黑色的3. 如果一个节点是红色的,则它的两个孩子结点是黑色的(树中没有连续的红色节点)4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点。原创 2023-01-28 19:55:02 · 5872 阅读 · 6 评论 -
C++——多态|多态的概念|多态的定义及实现|虚函数|多态的原理|虚函数表构成虚表的条件
多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如Student继承了Person。Person对象买票全价,Student对象买票半价。那么在继承中要构成多态还有两个条件:1. 必须通过基类的指针或者引用调用虚函数2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。原创 2022-11-04 18:24:05 · 678 阅读 · 36 评论 -
C++——二叉搜索树
若要删除8,这里采用右树最左节点的替换法,右树的最左节点就是10自己,如果这样写会有错误,while循环都不会进去,minparent就是空,而后面minParent->_left = min->_right;用左子树的最大节1点或右子树的最小节点4,若采用右树的最小节点,交换3和4删除4之后,删除3,但还有一个子节点5,我们让5成为6的左节点。若果要删除跟节点,而且左为空,若要删除8,我们更新根节点即可,让根节点指向10。若果要删除跟节点,而且右为空,若要删除8,让根节点指向3即可。原创 2022-11-30 20:54:57 · 1913 阅读 · 58 评论 -
C++——多态2|virtual与析构函数|C++11override 和 final|重载,重写(覆盖),隐藏(重定义对比| 抽象类|子类和父类虚表|多继承|习题|总结
目录virtual与析构函数 C++11 override 和 final重载,重写(覆盖),隐藏(重定义)对比 抽象类 子类和父类虚表 多继承 习题 多态总结 习题原创 2022-11-06 10:52:27 · 1550 阅读 · 35 评论 -
猿创征文|C++——继承|继承的概念及定|继承中的作用域|基类和派生类对象赋值转换|子类的默认成员函数构造函数|拷贝构造|赋值重载|析构函数|总结|继承与静态
封装:数据和方法放到类里面继承:继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。如下面这些职业都有相同的信息,我们可以把共有的数据和方法提取到一个类中,这个类叫父类继承的意义:复用,体现的是类设计定义层次的复用下面我们看到Person是父类,也称作基类。原创 2022-11-01 10:46:40 · 413 阅读 · 39 评论 -
C++——stack|queque|容器适配器 栈的实现 queque实现 dequequedequeque的缺陷 优先级队列习题 优先级队列模拟实现 仿函数
而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是,STL用其作为stack和queue的底层数据结构。vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是必vector高的。跟sort不同,sort传的是函数模板,传的是对象,而这里传的是类模板 ,传的是类型。后面俩个参数给缺省值,测试优先级队列,默认大的优先级高。原创 2022-10-17 14:49:20 · 796 阅读 · 37 评论 -
C++——反向迭代器|反向迭代器的实现|非类型模板参数|函数模板特化 |类模板特化|全特化偏特化(半特化)|模板分离编译模板总结
【优点】1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生2. 增强了代码的灵活性【缺陷】1. 模板会导致代码膨胀问题,也会导致编译时间变长2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误。原创 2022-10-24 18:20:38 · 225 阅读 · 41 评论 -
C++——list模拟实现|节点初始化迭代器|list功能实现|注意事项|insert |erase 析构函数|拷贝构造函数|operator=完整代码
因为形参用const修饰,在调用begin 胡哦end这些成员函数的时候要用const修饰它们,否则会报错,也就是说我只能调用const修饰的函数,此时就需要const迭代器。这里的迭代器是一个了类,并不是简单的指针,只不过这个类里面有个Node*的指针,要访问某个位置,不能用迭代器去直接访问,而是用类里面的指针去访问。在模板参数里多加俩个参数,使其泛型化,不用像之前那样写T&或T*,那样会写死,现在这种写法你传过来是什么,我就是什么,这样写会更加灵活。我们没写拷贝构造函数,此时进行拷贝构造是浅拷贝。原创 2022-10-19 14:04:01 · 688 阅读 · 7 评论 -
C++——vector模拟实现
str是一个用来临时存储组合的结果,digits是用户输入的数字,di是下标,如digits是“238”,di=0,就代表表示字符2,所以要给-'0',把每个按键对应的字母存到一个数组中,通过下标来访问。这是因为pos的修改不会影响p,pos是形参,p有可能会失效,有可能不会失效取决于有没有扩容,所以在p位置插入数据后,不要再去访问p,因为有可能会失效。这里传参的时候不进行引用传参,他会调用拷贝构造,根据我们写的拷贝可知,实参会被删除,保留形参,v就是保留下来的形参,然后跟一交换即可,这样比较方便。原创 2022-09-21 12:03:47 · 1020 阅读 · 34 评论 -
猿创征文|——C++|vecotor
vector原型为俩个模板参数,allocator是空间配置器(内存池)原创 2022-09-13 08:00:00 · 510 阅读 · 11 评论 -
猿创征文|——C++|string类模拟实现|构造函数的实现|operator和迭代器拷贝构造|赋值运算符重载|reverse|push_back|operator+= |append
调用析构函数的时候先把str2的_str置空,但可以看到s1的_str没被置空,也就是说存储数组的地址析构完str2的之后,已经变为空了,但是s1的_str仍然指向这块位置,接下来系统会对s1进行析构,对s1一析构就报错,因为这块空间已经被释放过一次了。但是存在一个问题,会和库里面的string产生差异,库里面不会打印拷贝构造的内容,而且输入的字符串如果很长,就会不断的+=,也就意味着要频繁的扩容,效率特别低。这个程序能完成拷贝构造,但是有一个缺陷,tmp是局部对象,出了作用域会调用析构函数,析构函数。原创 2022-09-12 07:58:54 · 497 阅读 · 102 评论 -
C++——string类
1. string是表示字符串的字符串类2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。3. string在底层实际是:basic_string模板类的别名,typedef basic_stringstring;4. 不能操作多字节或者变长字符的序列。在使用string类时,必须包含#include头文件以及using namespace std;原创 2022-09-09 08:24:50 · 517 阅读 · 49 评论 -
猿创征文——C++|string类2
assign相当于赋值语句insert插入,可插入某个string对象,字符串,字符,在某位置前插入若想在空格处插入%20,下面这种写法会出问题当遇到空格之后,insert会把%20插入到空格前面,然后把其余字符串往后挪,而插入之后,i还在原来位置,往后遍历又会遇到空格,所以程序会陷入死循环修改每次i插入后的位置,程序正常运行若想吧空格替换为%20erase是用来删除的从0这个位置开始删除len个字符如果len>剩余字符串长度,则有多少删除多少,删到结尾。原创 2022-09-11 08:32:09 · 752 阅读 · 34 评论 -
猿创正文|C++——模板初阶|泛型编程|函数模板|函数模板概念 |函数模板格式|函数模板的实例化|模板参数的匹配原则|类模板 |类模板定义格式|习题
class 类模板名{// 类内成员定义};对于之前我们写的栈类型{private:int top;};return 0;}如果创建俩个变量st1要求数组是char类型,st2要求是int类型,上面写的这种栈实现起来比较麻烦我们可以用类模板来解决上面这个问题{public:_top(0){{}}private:T* _a;int _top;};int main(){//类模板都是实例化。原创 2022-09-07 08:00:00 · 422 阅读 · 15 评论 -
猿创征文|C&C++——内存管理|内存区域划分介绍|内存分布C++内存管理方式|operator new与operator delete函数 |
我们平时写的代码是以文件的形式存在磁盘上编译链接->可执行程序(.exe等)可执行程序还是一个文件存在磁盘上,该文件主要部分是二进制指令代码和数据不同的数据要放到不同的区域(这些区域是操作系统划分的)加载的主要数据是全局变量,常量数据,把二进制指令加载到代码段,堆和栈的数据此时不开,栈上的区域是在建立栈帧的时候开辟的,堆上的是通过动态内存管理进行空间开辟或是释放的。原创 2022-09-05 08:00:00 · 1940 阅读 · 192 评论 -
猿创征文|C++——类和对象4| 构造函数体赋值|初始化列表explicit关键字|匿名对象|static成员|静态成员变量|静态成员函数| static相关习题|友元
目录再谈构造函数 构造函数体赋值 初始化列表explicit关键字 匿名对象 static成员 静态成员变量 静态成员函数 static相关习题 友元内部类 习题 下面代码共有多少拷贝构造原创 2022-09-02 08:00:00 · 536 阅读 · 61 评论 -
C++——类和对象3|日期类型|Cout运算符重载|Cin运算符重载|const成员|
Date*类型。原创 2022-08-31 08:00:00 · 1050 阅读 · 66 评论 -
C++——类和对象2|构造函数|析构函数|拷贝构造函数|运算符重载|赋值运算符重载|赋值运算符连续赋值
拷贝构造还有深浅拷贝问题,后面的博客里会写浅拷贝举例这里能正常拷贝,但是在析构的时候会崩溃这是因为这里执行了俩次析构函数,由于这里是直拷贝,st和st1指向了同一块空间,而这快空间被释放了俩次, 因为这里是内置类型,指针是内置类型,把*array所指向的空间给st1拷贝过去了,然后st1和st指向了同一块空间,析构的时候又free了俩次,直接崩溃。......原创 2022-08-30 08:00:00 · 306 阅读 · 54 评论 -
C++——类和对象
{// 类体:由成员函数和成员变量组成};// 一定要注意后面的分号class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的方法或者成员函数。C++中有访问限定符把刚才的struct改为calss,初始化的时候会报错这是因为struct默认的访问权限是public,class是private。原创 2022-08-27 08:00:00 · 533 阅读 · 59 评论 -
C++——内联函数|auto关键字
点击跳转_C语言宏知识讲解C语言中,宏有一些缺点如:可读性差,没类型安全检查,不方便调试 ,C++中为了解决这个问题,提出了内联函数以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。先观察下列函数的反汇编,这个call指令就说明创建了函数的栈帧,也就是当前情况下函数没有被展开,如果函数被展开了就不会创建栈帧当我们加上inline,再观察此时反汇编里仍然有这个call指令,说明加了inline之后还是会创建栈帧。原创 2022-08-26 08:00:00 · 806 阅读 · 21 评论 -
C语言为什么不支持函数重载?C和C++程序怎样互调?
在搞清楚这个问题之前,我们先弄清楚程序环境和预处理预编译阶段:生成test.i文件编译阶段:test.i文件变为test.s文件,这个时候建立栈帧给局部变量开空间等等汇编阶段:test.s文件变为test.o文件,符号表就是会给这些全局或函数变量一个地址链接:将同一个项目下的.o文件合并,生成.exe文件 ,这个阶段会进行符号表的重定位(重新进行全局变量或函数的地址匹配)原创 2022-08-25 07:46:39 · 652 阅读 · 33 评论 -
C++——关键字|命名空间|输入&输出|缺省参数|函数重载|引用
C语言中定义一个变量可能会跟一些函数名发生冲突,C++中为了解决这个问题 提出了namespace这个概念用namesapce来定义一个域, 若要使用这个域内的变量,我们使用域名::变量名,说明变量出处即可使用如若不 说明变量出处则是一个随机值::叫作用域限定符,这样可访问全局变量a命名的空间内可定义变量,函数,结构体,使用的时候需要声明命名空间{{}{int val;};}命名空间可以嵌套{int a;int b;{}{int c;int d;{原创 2022-08-23 08:00:00 · 990 阅读 · 27 评论