map和set的封装学习笔记

在学习了红黑树、map和set的使用后,来看看map和set的是如何将这颗树封装起来的。

理解图

这里的封装相比前面学习的容器更为复杂,所以画了伪代码图来理解,附带说明

具体实现代码可以参考

map和set的封装

一些细节

当然在实现上仍有很多细节需要注意,同时以往很多语法知识都忘记了,特别是关于const修饰(在实现const迭代器的时候踩了很多坑才发现的),所以在这里总结一下

为什么用于提取键的类需要在Tree中实例化?

模板参数中的keyofvalue本质是一个类类型,仿函数本质是这个类的成员函数,而非静态成员函数一定会带有this指针,而除了静态成员函数和不调用内存的成员函数不依赖this指针,其它所有成员函数都要求类先实例化,**才能确定this指针,**从而对成员进行访问。

为什么被const迭修饰的begin/end必须对this指针进行const修饰才能用?

调用const begin的可以是普通map对象,也可以是const map对象,而const对象只能看到带被constconst后缀的函数 (防止修改this指针所指向的对象),所以为了让const对象看到并使用,必须 提供一个带const 后缀的begin函数

为什么迭代器后置++返回值不能带引用?

因为在函数内部创建的temp是一个临时变量,肯定不能用引用接受的,而是要创建副本返回

既然前面提到const对象只能看到带被constconst后缀的函数,为什么还要强调类里面的函数参数如果可以尽量使用const修饰呢?

有如下三点原因:

1.为了接纳临时对象和常量,例如string str="dadadad";传进去右值,不能用左值来接收

2.防止修改传进来的参数本身

3.即便参数本身是否被修改不重要,并不代表它可以肆意修改传入的参数,比如在函数内部不小心修改了参数,又赋值给成员变量,而原本预计的就是要把参数原封不动地套用

区分const iterator和const_iterator,const iterator

const iterator导致iterator中的成员node*被const修饰 ,也就是变成了node* const node_ ,此时无法对_node这个指针进行修改(如不能++--)但可以修改其中指向的值 。而const_iterator接收了const T* 这个模板参数,这种写法本身就是不能对T指针指向的内容进行修改 ,迭代器内部可能修改所指向内容的函数只有解引用相关的函数 (->和*),而此时它们的返回值是const T&和const T*,所以能够保证迭代器指向的对象内容不被修改。

const 对象的上下文中,编译器会把所有成员变量视为 const 类型。任何试图修改它们的代码(哪怕是在类的内部函数里),都会直接报编译错误

template<class const T> 是非法语法,classtypename 后面只能跟标识符,所以只有在定义类的时候选择是否传const类型

另外一些心得:

map和set我在实现之前其实没使用明白,所以对功能的理解错误,导致实现时存在有很多误区,特别是插入函数对返回值的要求。应当先理解需求,再实现。

画图可以理清思路,后面工程代码量的不断增加,封装不断变得复杂,可能仍要用画图来理解

相关推荐
CSharp精选营2 小时前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
用户8055336980310 小时前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
BadBadBad__AK1 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
卷无止境1 天前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
卷无止境1 天前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端
郝学胜_神的一滴2 天前
CMake 30:循环语法全解|foreach_while双循环精讲、迭代技巧与实战避坑指南
c++·cmake
刘马想放假3 天前
Modbus 全栈技术解析:TCP、RTU、ASCII、RTU over TCP
数据结构·网络协议
北域码匠4 天前
冒泡排序太慢?鸡尾酒排序双向优化,原生 C# 零第三方库完整代码
数据结构·排序算法·泛型·c# 算法·鸡尾酒排序·原生 c# 开发·冒泡排序优化·嵌入式算法
卷无止境4 天前
C++ 的Eigen 库全解析
c++
卷无止境4 天前
现代 C++特性大盘点:一门脱胎换骨的老语言
c++·后端