C++
文章平均质量分 94
风起、风落
大三在读 但行好事,莫问前程
展开
-
【五一创作】|【C++】AVL树的实现
parent的右子树连接新节点为例,出while循环后,需要反向链接父节点,而此时的父节点就为刚才记录cur前一个节点的parent。插入前parent的平衡因子是-1或者1,插入前一边高一边低,插入节点到矮的那边,高度不变。双旋后 subl的平衡因子为-1,subLR的平衡因子为0,parent的平衡因子为0。双旋后 subl的平衡因子为0,subLR的平衡因子为0,parent的平衡因子为1。双旋后 subl的平衡因子为0,subLR的平衡因子为0,parent的平衡因子为0。原创 2023-05-03 09:54:21 · 1537 阅读 · 119 评论 -
【C++】特殊类的设计 | 类型转换
p作为一个指针,i作为一个int类型变量,虽然都是4个字节,但是意义不同,所以不能互相转,只能进行显式类型转换。因为编译器进行优化,把a的值放入寄存器中,而b所修改实际上是寄存器的a值而不是内存中的a值,所以a依旧为10。2.若两个单例都是饿汉,并且有依赖关系,要求单例1先创建,单例2再创建,饿汉无法控制顺序,懒汉才可以。dynamic_cast 会先进行检查,若指向父类对象,则转换失败,若指向子类对象,则转换成功。(两者是懒汉,则都是使用 成员的静态指针进行new创建对象的,谁先new是控制不住的。原创 2023-07-25 13:58:47 · 673 阅读 · 93 评论 -
【C++】智能指针
出了作用域,先将n2节点析构,使其引用计数减1,此时n2的引用计数为1,还有一个_next的智能指针指向n2,若p2处new抛异常,则相当于p2的new没有成功,而p1的new成功了,所以需要释放p1,然后再重新抛出。若将对象C赋值给对象A,则使对象A指向对象C的资源处 ,同时对象B的引用计数-1,对象C的引用计数+1。再将n1节点析构,使其引用计数减1,此时n1的引用计数为1,还有一个_prev的智能指针指向n1,为了解决这个问题,就增加一个引用计数,若只有一个对象,就为1,若为两个对象,则为2。原创 2023-07-23 12:51:07 · 818 阅读 · 74 评论 -
【C++】异常
,若有匹配的就用匹配的,若没有匹配的,就使用catch(…则当b为0时,由于Func函数处 更近,所以在Func函数处捕捉异常,而不在main函数中捕获异常。此时Func函数中的捕获异常与对象类型不匹配,当再次输入b为0时,在main函数处 捕获异常。当在Func函数中的catch要捕获异常时,再将异常抛出,使main函数中进行 捕获异常。抛出异常对象后,会生成一个异常对象的拷贝,因为抛出的异常对象可能是一个临时对象,异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个catch的处理代码。原创 2023-07-04 20:24:34 · 563 阅读 · 45 评论 -
【C++11】 包装器 | bind
bind的参数包作为占位符,借助placeholders 命名空间 来访问里面的字符(_1 _2)_1表示第一个参数,_2表示第二个参数 ,但默认情况下获取不到 (_1 和_2被放到命名空间中)arg_list中的参数可能包含形如_n的名字,其中n是一个整数,这些参数是占位符,但在调用时,一个调用的是f函数,一个调用的是Functor中的operator()想要声明出统一的类型,就需要借助包装器进行包装,从而适配出统一的可调用对象的类型。正常情况下,把1传给参数a,把2传给参数b ,打印a=1 b=2。原创 2023-07-03 20:45:24 · 515 阅读 · 111 评论 -
【C++11】移动赋值 | 新的类功能 | 可变参数模板
正常来说,str作为局部变量,应该作为左值,但编译器会对其优化,通过使用move函数,其函数返回值为右值,所以会先发生移动构造。对于自定义类型成员 _name,因为在yzq命名空间的string类中存在 移动构造,所以调用 其移动构造。当test函数内部再次调用 test时,由于参数包参数为0,所以去调用 无参的test ,进行换行。本来只有两次深拷贝,但是由于调用拷贝赋值时,内部又进行一次拷贝构造,所以导致最终进行三次深拷贝。若没有实现移动赋值,并且没有实现析构函数、拷贝构造、拷贝赋值重载中的任意一个。原创 2023-06-12 13:54:43 · 1044 阅读 · 92 评论 -
【C++11】 initializer_list | 右值引用 | 移动构造 | 完美转发
左值引用减少拷贝,提高效率右值引用也是减少拷贝,提高效率但角度不同,左值引用是直接减少拷贝右值引用是间接减少拷贝,识别出是左值还是右值,若识别出是右值,则不再深拷贝,直接移动拷贝(资源转移),提高效率。原创 2023-06-09 13:50:09 · 1937 阅读 · 96 评论 -
【C++】位图应用 | 布隆过滤器
优点:速度快 节省空间缺点:只能映射整形,string 浮点数 不能存储映射所以提出布隆过滤器,用于一定程度解决 不能存储string类型的问题。原创 2023-06-02 23:36:41 · 608 阅读 · 61 评论 -
【C++】unordered_set 和 unordered_map 使用 | 封装
哈希桶HashBucket中需要将其内部的HashNode 的参数进行修改将原来的模板参数 K,V 改为 T同样由于不知道传入数据的是K还是K V类型的 ,所以 使用 T 类型的data代替之前实现的模板参数 K ,V分别代表 key 与value修改后 , 第一个参数 拿到单独的K类型,是为了 使用 Find erase接口函数的参数为K第二个参数 T 决定了 拿到的是K类型 还是 K V 类型。原创 2023-05-27 13:23:44 · 2098 阅读 · 40 评论 -
【C++】 哈希
需要使用枚举来表示三种状态 删除 存在 空表示状态的state 也应该默认设为空,不然有可能造成 映射位置 没有数据但是 状态为存在的情况。原创 2023-05-20 15:27:53 · 2260 阅读 · 101 评论 -
【C++】map和set的封装
原本自己实现的红黑树 模板为 template第一个参数代表 key ,第二个参数 代表 value把第二个参数 改为 T 即 template按照STL的写法,使用第二个模板参数决定树的节点原本的kv包含K V ,但是由于要调用map 和set,所以不知道到底传过来的是什么所以使用 模板类型的 data 代替在结构定义时,为了让map与set都能调用同一颗红黑树,所以把模板参数改为T。原创 2023-05-14 23:43:07 · 778 阅读 · 85 评论 -
【C++】红黑树
使用枚举来记录红色与黑色,用_col表示当前节点颜色但是在构造函数中为什么默认是红色呢?为什么不能是黑色呢?原创 2023-05-13 08:07:24 · 866 阅读 · 94 评论 -
【C++】set和map的使用
对于STL容器来说,有很多相似的功能,所以这里主要将与之前不同的功能说清楚。原创 2023-04-29 17:25:37 · 1520 阅读 · 101 评论 -
二叉树OJ题(C++实现)
主要思路是借助一个队列,将每一层的数据以size统计,当size为0时说明该层数据已经输入完,将这一层的数据传入vector中,再通过push_back 传入 vector< vector< int >中。若两个节点都在根的左子树,则递归根的左子树的节点为根,当这个根为两个节点其中一个时,则这个节点就为公共祖先。若两个节点都在根的左子树,则递归根的左子树的节点为根,判断两个节点是否为根的左右子树,直到寻找到。若一个在根的左子树,一个在根的右子树 , 则根就为公共祖先。节点5与节点4的最近公共祖先是节点5。原创 2023-04-23 22:05:43 · 721 阅读 · 111 评论 -
【C++】二叉搜索树
从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。最多查找高度次,走到到空,还没找到,这个值不存在非空右子树的所有值大于根节点的值左右子树都是二叉搜索树第一个不满足,因为值为5的节点在值为10的节点的右边,正常来说10的右边都应该比10大分为两种情况若插入的值在二叉树中不存在,则通过比较进行插入若插入11,因为11比8大,所以跟10比较,而11比10大,所以走10的右子树14,14与11比较,因14>11,所以走14的左子树13,11与13比较,因13>11,故作为13的左子树,遇见NU原创 2023-04-18 09:34:27 · 934 阅读 · 131 评论 -
【C++】多态(下)
ptr2并没有指向子类对象的开始,此时调用子类对象的func1函数,this指针指向中间的位置不对了,所以需要修正this指针,使之指向子类对象开始的地方。写的并不对,d本身是一个Derive类型,&d后变为Derive* 的一个指针,+1 跳转的是Derive类型的字节大小。首先取到Base* ,将其强制转换为int*,代表前四个字节的地址,再解引用是int类型,把前四个字节取出来。base1的虚表指针 正好在对象的前4个字节处,直接可以使用求出虚表指针 去指向base1的虚表。原创 2023-04-05 20:51:25 · 1283 阅读 · 96 评论 -
【C++】多态(上)
多态的条件:1.虚函数的重写----三同 (函数名、参数、返回值相同)2.父类的指针或者引用去调用在虚函数后面写上=0,这个函数被称为纯虚函数,包含纯虚函数的类叫做抽象类,抽象类不能实例化对象若创建一个子类继承抽象类,则该子类也包含纯虚函数,子类也会变成抽象类,所以子类创建对象也会报错。原创 2023-04-04 20:47:25 · 812 阅读 · 77 评论 -
【C++】继承(下)
这样看似是调用了3次A的构造函数,但是实际上通过使用虚继承,所以只有一份A的数据,是单独调用的那份A数据。因为B类和C类中都存在A,存在数据冗余和二义性,所以把A的数据放入公共区域,既不放入B中,也不放入C中。通过初始化列表去调用B这个类,而B类是继承父类A的,在调用B类的构造函数时,需要先调用A类的构造函数。初始化列表去调用C这个类,C类是继承父类A的,在调用C类的构造函数时,需要先调用A类的构造函数。由于A是B和C的父类,所以A类的_a在B类和C类中都存在。原创 2023-03-30 11:57:48 · 361 阅读 · 21 评论 -
【C++】继承(上)
实际当中基类都是public/protected成员,派生类基本都是public继承这个块平时使用最多。原创 2023-03-28 21:10:10 · 458 阅读 · 68 评论 -
【C++】模板进阶
此时在预处理阶段将头文件展开,由于声明和定义都在一起,所以此时add函数 call时有地址存在,不需要向func一样,链接时去寻找函数地址了声明和定义放在一起,直接就可以实例化,编译时就有地址,不需要链接1. 模板会导致代码膨胀问题,也会导致编译时间变长模板会进行实例化,所以运行时间变长,因为是一个模板,若传过来int 、char、double 类型都要实现,所以代码会膨胀2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误。原创 2023-03-23 18:04:27 · 566 阅读 · 32 评论 -
【C++】list的模拟实现
C++中,Listnode作为类名,而next和prev都是类指针,指针引用成员时使用->,而对象引用成员时使用 .若在数组上有一个int类型的指针,解引用是int类型的数据,再++可以加载下一个位置,因为物理空间是连续的。erase函数执行后,it所指向的节点被删除,因此it无效,在下一次使用it时,必须先给it赋值。同样若在链表上,解引用类型为 node,再++不能到下一个节点,因为物理空间不连续。++pnode,找到下一个节点的地址,但是下一个节点不一定是要的节点。原创 2023-03-11 18:00:50 · 1306 阅读 · 67 评论 -
【C++】vector的模拟实现
为了避免缩容的情况,所以使用 n>capacity() , 开辟一块空间tmp,将start中的数据拷贝到新空间,释放旧空间,指向新空间,同时更新_finish 和_end_of_storage。深拷贝是重新开辟一块与原空间大小相同的新空间,并将原空间的数据拷贝给新空间,但是若为string 类型,本身的_str指向字符串,而新空间只是将_str拷贝过去了,依旧指向同一字符串。扩容时出现了问题,由于pos指向原来的空间,但是扩容时将释放了旧空间,但是pos依旧指向原来的空间,所以pos变成了。原创 2023-03-07 10:16:17 · 1696 阅读 · 94 评论 -
【C++】string的模拟实现
string底层是一个字符数组为了跟库里的string区别,所以定义了一个命名空间 将string类包含。原创 2023-02-24 09:00:52 · 1705 阅读 · 89 评论 -
【C++】string类(下)
但string类的swap只能针对string完成交换,而类模板的swap,可以对任意类型完成交换。s.rbegin()返回指向最后一个位置的指针,s.rend()返回指向第一个位置前一个的指针。s.begin()返回指向第一个位置的指针,s.end()返回指向最后一个位置的下一个的指针。s.begin()代表开头的位置,s.begin()+5代表1的位置,在1之前插入字符!修改s1指针指向原来s2指向的空间,修改s2指针指向原来s1指针指向的空间。当函数的参数为const时,需要返回const的迭代器。原创 2023-02-17 15:40:04 · 957 阅读 · 15 评论 -
【C++】string类(上)
ASCII是美国标准信息交换代码,用来在计算机里面存储和显示英文信息,通过26个字母、数字、标点符号,来建立关系形成映射表从而生成了编码表,调用对应的ASCII值来生成对应的符号,ASCII表只有128个字符,一个字节8个bit位就够了。c语言的字符串是以’\0’结尾的一些字符的集合,比如存储你的家庭住址,修改成为新的住址,原来的住址短,现在的住址长,之前的字符串数组存不下,不能很好按需修改。string()——构造空的string类对象,即空字符串。c++提供一个类来管理字符串,这个类就叫string。原创 2023-02-15 22:10:55 · 646 阅读 · 24 评论 -
【C++】模板初阶
class 类模板名// 类内成员定义public ://析构函数类中的声明 private :T * _pData;template < class T > //析构函数在类外面定义 要加上模板 Vector < T > :: ~ Vector() {return 0;以析构函数为例,在类里面声明,在类外面定义对于模板,vector是类名,但不是类型,加上实例化的模板参数后才是类型,如vector。原创 2023-02-14 12:41:35 · 745 阅读 · 30 评论 -
C++内存管理
申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[]class A {public :} ~ A() {int _a;free(p);return 0;申请2个A类型的空间,调用2次构造函数释放空间,并调用2次析构函数虽然写入了malloc在堆开辟10个A类型空间,free释放空间,但是没有调用构造和析构函数在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。原创 2023-02-13 21:05:47 · 985 阅读 · 65 评论 -
类和对象(下)
而横线下面先是在主函数中 A b构造一次 ,调用func4函数, A a构造一次 ,return a拷贝构造生成一个临时变量,由于此时的b已经被定义雇过了,所以此时 属于将临时变量赋值给 b ,进行运算符重载。因为通过构造生成一个类型为A的临时变量,而临时变量具有常性,ret为临时变量的别名, 将临时变量传过去,由const A类型到A类型会造成权限放大,所以要加const修饰ret,说明临时变量的存在。3.成员变量在类中的声明次序就是在初始化列表中的初始化顺序,在初始化列表中的先后次序无关。原创 2023-02-11 13:22:41 · 998 阅读 · 81 评论 -
日期类的实现
include "date.h" //函数实现 int date :: getmonthday(int year , int month) {//是闰年并且是2月份 return 29;//判断日期是否合法 if(month > 0 && month < 13 &&(day > 0 && day原创 2023-02-09 12:50:12 · 868 阅读 · 36 评论 -
类和对象(中)
public :Time() //默认构造函数 {_hours = 0;int _hours;public ://没有构造函数,则编译器会自动生成一个无参的默认构造函数 void print() {int _year;int _month;int _day;Time _t;//调用自定义类型 };date d;//无参数 d . print();return 0;在date类中又定义了一个自定义类型time自定义类型成员会调用它的默认构造函数(不用传参数的构造)原创 2023-02-08 11:30:45 · 1469 阅读 · 79 评论 -
C++类和对象(上)
默认访问限定符不同struct listnode_CPP //使用struct {int val;使用struct 默认访问限定符为 public (共有的),在类外面可以访问到class listnode_CPP //使用class {int val;使用class 默认访问限定符为private(私有的),在类外面不能访问到public ://成员函数 private :int a;//成员变量的声明 };stack s1;//相当于将成员函数整体定义 return 0;原创 2023-02-06 20:04:21 · 700 阅读 · 51 评论 -
【C++】引用 | auto类型 |范围for |使用nullptr的原因
int a = 10;int & b;//错误举例 return 0;若使用引用不初始化,b是谁的别名?原创 2023-02-03 12:14:33 · 1327 阅读 · 75 评论 -
c++入门(命名空间+缺省参数+函数重载)
当函数的声明和定义都在存在缺省参数时,调用就会报错一般来说,在函数声明时存在缺省参数。原创 2023-01-07 13:23:20 · 1291 阅读 · 59 评论