c++进阶
文章平均质量分 87
虚舟游梦
在校大学生,在进行c/c++的学习。
展开
-
map和set的使用
multimap的使用和map大致相同,但因为multimap的key会对应多个value,所以multimap没有operator[]函数,这也是map和multimap最大的区别,还有一些区别,比如insert的返回值,与map不同,multimap的插入是必定成功的,所以multimap插入函数的返回值是iterator。set是一个模板,T就是key,compare则是比较方式,如果默认的less不符合要求,比如指针,要求按指向数据的大小比,而不是按指针地址比,就需要自己写比较方式。原创 2023-08-09 18:10:17 · 221 阅读 · 0 评论 -
二叉搜索树的模拟实现
以图示搜索树为例,如果要找8,8比6大,必然在6的右子树,8比9小,必然在9的左子树,8又比7大,在7的右子树,找到8。基础的二叉树用的其实不多,二叉树的重点在二叉树的延伸:二叉搜索树。//数值交换后,新的树依然满足搜索二叉树,交换的值是右子树的最小值,且比key大,key一定还是新树的最小值。//找到删除节点左子树中最大的节点,或者右子树中最小的节点,替换原来节点中_key的值,再删除找到的节点。//节点与子树的关系,比如将根节点与根的左节点交换,根节点就会变成原树的左节点,树会变成原树的左子树。原创 2023-08-01 23:05:08 · 256 阅读 · 0 评论 -
关于vs下多态虚表中存储的地址和实际成员函数地址不一样的原因
编译正常,B,C中各有一个虚表,可以储蓄对A中虚函数的重写,但是,如果B,C是虚拟继承就会报错,在虚拟继承下,B,C中存储A的未知统合为一块区域,(B,C中存储指向虚基表的指针,指针指向的虚基表中存储有对A区域的偏移量)这样就会导致编译器不知道在A的虚表中储存B中的重写,还是C中的重写。虚表中存储的地址是edx存储的地址。这是因为vs对成员函数实现了封装,虚表中储存的地址是封装位置的地址,虽然存储的地址不一样,但是最终还是调用到了Derive::func1,说明还是跳转到func1的位置了。原创 2023-08-01 23:04:29 · 338 阅读 · 0 评论 -
多态的原理
那么具体是哪一个呢?对d的地址解引用拿到d的全部空间,对d的地址前4个字节解引用(如果是64位,要取前8字节),拿到_vfptr中存储的数据(_vfptr的地址和d是一样的,_vfptr是指针数组首元素的地址,不是首元素),此时为int类型的变量,强转为func类型的后传入print函数的参数a中,a[i]调用虚表中的第i个数据,加上函数调用符'()',调用指针指向的函数。答案是会调用派生类的虚函数,这就违反多态的规定(指向什么类型,调用什么类型的虚函数,明明指向的是一个基类,却调用了派生类的虚函数)了。原创 2023-07-14 20:31:50 · 195 阅读 · 0 评论 -
多态的基本使用
所以在继承的部分,在派生类的析构函数中调用基类的析构函数且不声明作用域会报错(虽然派生类会在结束自动调用基类的析构函数,不需要再调用,但这里只是解释一下为什么在派生类调用基类的析构函数会报错,即使派生类和基类都没有成员变量(有成员变量就可能需要释放空间,对一个空间释放两次就会报错)),两种析构函数都被处理成destructor的形式了,会导致无限递归。虚函数的重写:派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数。原创 2023-07-14 20:31:39 · 357 阅读 · 0 评论 -
菱形继承及菱形虚拟继承
可以看到两个指针直接指向的位置都为0,直接指向位置的下一个位置则是两个数字,B为20,C为12,这个20,12实际上是偏移量,用来指向_a所在的位置,在B中存储指针的位置向下偏移20,就得到_a的位置。顺便说一下,当数据的情况复杂到一定程度,vs编译器的监视窗口就不一定准确了(vs2013对下面的代码显示不准确,vs2019能正确显示,但是要深入了解虚拟继承如何解决问题,还是得用内存窗口),这时要想得到准确的数据就要使用内存窗口。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂。原创 2023-07-04 17:27:54 · 302 阅读 · 0 评论 -
继承的基本内容
当然派生类天然赋值给基类的前提条件是public继承(基类成员变量被public和protected修饰都可以将派生类赋值给基类),如果是protected继承,继承的基类会变成protected成员,在student类类外是不能访问(读取也算访问)继承的基类部分的,就不能将派生类的基类部分赋值给基类。如图所示,基类和派生类中存在相同的变量名_num,在没有指定作用域时,在派生类中访问_num时,基类的_num会被隐藏,也就是说,只会访问到派生类的_num。派生类赋值给基类,就是将基类的部分依次赋值过去。原创 2023-06-23 19:03:10 · 245 阅读 · 0 评论