
新C++
文章平均质量分 92
本专栏用于对C++中的一些零星语法细节进行探讨。
仅供学习、参考。
WGzZsyu
感谢你的关注
展开
-
C++附加篇: 空间适配器
STL的六大组件,容器、算法、迭代器、适配器、仿函数,最后一个也就是"空间适配器"。 所谓"空间适配器",顾名思义,就是对STL中各个容器的内存进行高效的管理。也许你会说,诶,我写了这么多的C++代码,为什么没有这个概念呢?或者说,为什么我们根本没有见到!这个空间适配器呢? 然而事实上,不是说,我们没有使用,而是在我们使用诸如vector\list\deque时,我们的空间配置器是在默默地为我们进行工作。原创 2023-04-19 15:52:35 · 592 阅读 · 0 评论 -
新C++(16):可变参数模板
但是,如果一个类没有提供"移动构造"或者“移动赋值”,那么此时无脑用emplace系列插入接口是完完全全正确的,且效率很高的。于是乎,有人就说,“要多使用emplace系列的插入版本,因为它比push或者insert系列的插入版本效率要高"。我们会发现,当我们使用printf函数时,它即可以接受0个参数,也可以接收1、2、3个参数。但是在C++11之前,函数模板和类模板的参数是固定的,C++11的新特性可变参数模板能够让您创建可以接受可变参数。上面的参数args前面有省略号,所以它就是一个可变模版参数。原创 2023-04-04 13:37:32 · 483 阅读 · 0 评论 -
新C++(15):可调用对象及包装
是的,这是一个经典的信号处理函数。函数指针的本质,就是函数入口的地址,但显然这对我们尤其是初学者特别不友好,这层层嵌套,何时才能嵌套得完?他们的功能如出一辙,但是唯一不同的是,我们在useF类中定义的静态成员变量Count是存在多份的。也就意味着,在useF实例化对象时,实际上是实例化出3份功能相同的函数的。显然,当面对这种情况,仿函数可以作为参数传递给一个类的模板作参数,仅凭这一点,仿函数的实用性其实就比普通函数广太多了。但是呢,C++引入了仿函数的语法之后,与普通函数相比较,仿函数的使用更加便利。原创 2023-03-18 20:22:14 · 562 阅读 · 0 评论 -
新C++(14):移动语义与右值引用
当你在学习语言的时候,是否经常听到过一种说法,"="左边的叫做左值,"="右边的叫做右值。从某种意义上来说,这句话只是说对了一部分。传统的C++语法中就有引用的语法,而C++11中新增了的右值引用语法特性。右值也是一个表示数据的表达式,如:字面常量、表达式返回值,函数返回值等等。,左值可以出现赋值符号的左边,也可以出现在等号右边。可以出现在赋值符号的右边。不能出现在赋值符号的左边。原创 2023-03-10 21:02:43 · 763 阅读 · 0 评论 -
新C++(13):布隆过滤器
你使用一个哈希函数,那么表示一个数值在不在的就是1bit,如果你用两个哈希函数,那么表示一个数值在不在的就是2bit,如果你用三个哈希函数……但是,你会发现,你就仅仅是在这不到10个数中,查找5,却开开辟了512MB空间用来标记。上篇呢,我们在遇到海量数据时,如果只是进行诸如,查找一个数在不在这样的简单逻辑情况,在使用数组这样的内存容器,无法存储这么多数据时,我们采用新的数据结构——"位图"。那如果此时给你一个全部用户的名单,你要在用户名单中找出进入黑名单的用户,并将它剔除,你如何快速找到该名字并判断?原创 2023-03-06 22:10:41 · 358 阅读 · 0 评论 -
新C++(12):位图与海量数据处理
一个树的节点,最起码就包含三叉链(left,right,parent)。想想看,这些庞大的数字堆积起来的内存空间是有多么可怖。得到一个有序序列,emm,然后可以通过二分查找,以LogN的效率查看该数是否存在。因此,用位图结构来处理大量数据时,对于存储数值在内存上的消耗能显著降低!此时,我们本来用一个4字节int或者1字节的char表示一个整数,变为用一个bit位来标识一个整数是否存在。emm,听起来不错,甚至我还想将这40多亿个整数放在红黑树、哈希表中查找。位图结构中,set、reset是最重要的。原创 2023-03-02 23:28:13 · 762 阅读 · 0 评论 -
新C++(11):unordered_map\set的封装
而在C++11中,STL又提供了unordered(无序)容器,其使用方式与map\set类似,但其底层不是红黑树的数据结构,而是一种哈希结构。不过值得关注的是,哈希结构存储时,需要上层传入"哈希函数"。我们, 又该如何做?HashData同上篇讲的红黑树结点Value一样,它们根本不关心你到底是传入的模型,还是就是模型。毕竟字符串等不是整数的类型是作为Key时的少数,大多数都是直接可以去key作为整数的取模。关于字符串的哈希函数,有很多前辈们都提供了一定的方法函数。原创 2023-03-01 15:41:47 · 485 阅读 · 0 评论 -
新C++(10):Map\Set的封装
在map、set没出来之前呢,我们存储数据常用的都是顺序表、链表、栈队列等这些都被称为"序列式容器"。如果我们想要存储一些关联式键值对,例如"名字:身份证号","商品名称:商品数量"等等以这样数值建立起来的模型,我们之前实现的Node结点都是模型,为什么源码中会这样声明了呢?不过在这之前,我们已经实现了一份红黑树的迭代器,我们正好可以继续完善原RBTree的代码,我们并非是要造轮子,阅读源码,汲取前辈们的智慧设计。我们先来看看STL源码中,是如何处理结点的值。原创 2023-02-24 21:45:27 · 408 阅读 · 0 评论 -
新C++(9):谈谈,翻转那些事儿
这样的树形结构,能够十分高效地查找"键值"(key/value模型)。C++中的STL容器,如map、set其底层就是由红黑树实现的。当然这是后半段会讲的一种优秀的数据结构。形如上图,每个节点的上标是该节点的左右子树的高度差。如果该AVL二叉树有N个节点,那么其高度可以保持LogN(以2为底),其搜索查找的时间复杂度为LogN(以2为底)。左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1)在AVL树中任何节点的两个子树的高度最大差别为1。它的左右子树都是AVL树。(1)什么是AVL树?原创 2023-02-21 19:37:01 · 471 阅读 · 2 评论 -
新C++(8):多态那些事儿_下
"当人类悬浮到腐朽,有谁愿追随彗星漂流哦~"一、多态原理(1)虚函数表指针(虚表指针)紧接上一篇sizeof(Base)这一小段说起。我们知道,两个Base虽然在成员上相差无几,但是因为虚函数的存在,Base2一定是 > Base1的。前篇说了这里的原因在于,一旦有虚函数,类里面就会自动生成一个虚函数指针。那么什么是虚函数指针呢?vfptr即虚函数表指针(虚表指针)是一个函数指针数组_vtable(2)虚函数表那么这个虚函数表在哪里呢?这个虚函数表有几份呢?原创 2023-02-03 20:25:57 · 731 阅读 · 0 评论 -
新C++(7):多态那些事儿_上
我们举一个买车票的例子,普通人买车票 对应的是"全价",学生呢买车票则对应的是"半价",军人买票呢,对应的是"优先买票"。似乎我们预想的是,让ptr2delete的时候,不是去调用它类型的析构,而是去调用new的对Student的析构。不管是student、soidler、person都传递给父类引用,但是因为多态的条件达成,那么传递的什么类型,就去调用什么类型中被重写(覆盖)。在继承中,我们层提到,在子类的析构函数中,不用显式去调用父类的析构函数,因为当子类的析构函数结束后,就会去调用父类的析构函数。原创 2023-02-02 21:00:17 · 1086 阅读 · 2 评论 -
新C++(6):继承那些事儿
事实上,不同类型的变量是不能进行这样的操作的,因此,为了保证可行性,这里会发生“隐式类型转换”。不是将i的值赋值给j,而是在这个过程中产生一个临时变量 ,先将i的值给临时变量,再由临时变量赋值给j。我们定义Student s,那么它不仅仅会去调用它自身的构造函数,还会去调用继承的父类对象部分的构造函数进行初始化。在本段的开头,我们就发现,当定义一个派生类时,即便我们在该类的析构函数中没有显式调用其基类的析构函数,但是最后打印出来却是调用了基类的析构函数。我们没有调用析构,为什么会自动调用父类的析构函数呢?原创 2023-02-01 20:16:29 · 292 阅读 · 0 评论 -
新C++(5):异常
其实从那一大串错误码+错误码描述信息,你就该知道,作为程序员如果仅仅拿到错误码,还得去挨个儿从0~100(假设)去寻找对应的错误信息,在"error=100","Network is down",噢~是这个问题。在实际中,都会定义一套规范的继承异常体系,这样大家抛出的都是继承后的派生类(derived),外层调用都可以捕获它们的基类(base)即可。前面举例异常重新抛出的时候,遇到了一个问题,那就是当释放资源的动作在受到异常抛出、捕捉的影响时,可能会被忽略掉,从而导致内存泄漏的问题。原创 2023-02-01 01:08:59 · 425 阅读 · 0 评论 -
新C++(4):模板
函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器。那么此时我们如果非要使用模板的 情况,就需要 显示调用模板。C++可复用性高,C++引入了模板的概念,后面在此基础上,实现了方便开发的标准模板库STL。这是一个 "党徽"的 模型。如果是想要鲜艳的红色, 直接可以在模板的基础上 浇筑红色颜料即可。了解的 函数模板的基本使用, 对于模板的原理 也有了一定的基础。C++的模板分为两类: 函数模板 + 类模板。原创 2023-01-09 15:43:42 · 426 阅读 · 0 评论 -
新C++(3):内存管理
6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理。当为 自定义类型申请空间的时候,new 会去调用 自定义类型的 构造函数,delete会 去调用自定义类型的 析构函数。new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间。2.内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。当然这不是本章的重点。原创 2022-10-19 15:41:29 · 480 阅读 · 0 评论 -
新C++(2):this\默认成员函数\初始化列表\static
定义时不添加static关键字,类中只是声明。3. 类静态成员即可用。原创 2022-10-13 16:52:10 · 446 阅读 · 0 评论 -
新C++(1):命名空间\函数重载\引用\内联函数
是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。C++引入“函数重载”后,从上层使用的角度上来看,调用的是同一个函数。但事实上,底层根据制定的规则,会去自动调用不同 的函数。达成函数重载的三种情况①参数类型不同②参数个数③参数顺序(2)函数重载的原理可能你会疑问,为什么函数重载C++支持,而C语言不支持呢?函数名修饰规则的不同。原创 2022-09-20 23:34:37 · 476 阅读 · 0 评论