![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C++
文章平均质量分 76
C++笔记
ls-R
这个作者很懒,什么都没留下…
展开
-
高并发内存池(回收)[4]
这段代码的作用是将Span回收给PageCache,并尝试进行前后页的合并,以缓解内存碎片问题。合并的条件包括前后页存在且未使用,并且合并后的Span的页数不超过NPAGES-1。这段代码的作用是将一组内存块释放到对应的Span中,并在Span的使用计数变为0时将Span回收给PageCache。的实现,用于将Span回收给PageCache,并尝试进行前后页的合并,以缓解内存碎片问题。的实现,用于释放一组内存块到对应的Span中。,分别表示要释放的内存块的起始地址和大小。原创 2023-08-22 15:09:03 · 1033 阅读 · 0 评论 -
高并发内存池(PageCache)[3]
共128页centralcache向pagecache申请2page时,首先向下扫描,有大的会切分出来,然后再挂在对应桶当中。原创 2023-08-21 11:13:46 · 148 阅读 · 0 评论 -
高并发内存池(centralcache)[2]
threadcache是每个线程独享,而centralcache是多线程共享,需要加锁(桶锁)一个桶一个锁解决外碎片问题:内碎片:申请大小超过实际大小;外碎片:空间碎片不连续,导致无法申请大块空间。原创 2023-08-18 20:33:05 · 262 阅读 · 0 评论 -
高并发内存池(threadcache)[1]
用FreeList做哈希桶的映射。原创 2023-08-17 21:57:09 · 104 阅读 · 0 评论 -
定长内存池设计ConcurrentMemoryPool
内存块自身进行链接,前四个字节存下一个的地址。原创 2023-08-14 22:35:03 · 182 阅读 · 0 评论 -
c++学习(多线程)[33]
本质封装操作系统的库事实证明,两个线程在cpu中交错运行thread传参为模板参数,应用折叠,都会变成左值,所以count还是0。原创 2023-08-13 12:01:21 · 973 阅读 · 0 评论 -
c++(空间配置器)[32]
迭代器提供了一种统一的访问容器元素的方式,可以通过迭代器遍历容器中的元素,实现对容器的操作。二级空间配置器使用了一些数据结构(如自由链表)来管理内存池,按照固定大小的块进行切分可以简化数据结构的设计和操作,从而提高内存分配的速度。空间配置器的碎片指的是内存中的小块未被使用的空间,这些空间可能散落在已分配的内存块之间,无法被有效利用。这个过程称为内存碎片的合并。需要注意的是,不同进程之间可以通过进程间通信的机制共享内存,但共享的内存通常是通过特殊的方式进行管理,而不是直接使用一个公用的空间配置器。原创 2023-08-09 15:16:27 · 847 阅读 · 0 评论 -
c++(IO流)[31]
要使自定义类型支持流插入和流提取操作,需要在类中重载相应的运算符。对于流插入操作,需要重载输出流运算符<<。该运算符接受一个输出流对象和一个自定义类型对象作为参数,并将自定义类型对象的数据输出到输出流中。原创 2023-08-08 11:13:54 · 90 阅读 · 0 评论 -
c++(类型转换+IO)[30]
在C++中,可以通过重载类型转换运算符(type conversion operator)来实现自定义类型到内置类型的转换。类型转换运算符是一种特殊的成员函数,用于将一个类类型转换为另一个类型。public :// 构造函数 MyInt(int v) : value(v) {} // 类型转换运算符 operator int() const {} };原创 2023-08-07 12:03:53 · 92 阅读 · 0 评论 -
c++学习(特殊类设计)[30]
如果你想要确保对象只能在堆上创建,可以通过将析构函数声明为私有,并提供一个静态成员函数来创建对象。这样,类的实例化只能通过调用静态成员函数来完成,而无法直接在栈上创建对象。如果你想要确保对象只能在栈上创建,可以将类的构造函数声明为私有,并提供一个静态成员函数来创建对象。这样,类的实例化只能通过调用静态成员函数来完成,而无法直接在堆上创建对象。懒汉模式在第一次调用获取实例的方法时才创建对象,而饿汉模式在类加载时就创建对象。这样,我们就可以确保对象只能在堆上创建,而无法在栈上创建。,我们可以在栈上创建对象。原创 2023-08-06 16:04:13 · 127 阅读 · 0 评论 -
c++学习(智能指针)[29]
它的基本思想是在对象的构造函数中获取资源,在对象的析构函数中释放资源,从而确保资源的正确获取和释放。在构造函数中,我们尝试打开指定的文件,如果打开失败,则抛出异常。RALL 的主要优点是可以避免资源泄漏和忘记释放资源的问题,提高代码的可靠性和可维护性。通过使用 RALL 技术,我们可以在对象的构造函数中获取资源,在析构函数中释放资源,从而避免了显式地调用获取和释放资源的函数,提高了代码的可靠性。其次,它的拷贝语义是通过所有权转移来实现的,即拷贝后原来的。,我们可以访问所管理的整数对象的值,并输出到控制台。原创 2023-08-04 12:50:04 · 62 阅读 · 0 评论 -
c++学习(异常)[28]
匹配优先调用链中最近的捕获原创 2023-08-04 11:06:56 · 76 阅读 · 0 评论 -
c++学习(lambda+bind)[27]
是 C++ 标准库中的一个函数模板,用于创建一个新的可调用对象,该对象将指定的函数或成员函数与一组参数绑定在一起。类型可以用来存储和调用各种类型的可调用对象,包括函数指针、函数对象、成员函数指针和 Lambda 表达式等。f1不能被f2赋值因为,f1和f2相当于不同的类,uuid不同,所以不能。类型来定义变量、参数和返回值,以存储和调用各种类型的可调用对象。下面这样是不允序的,因为a已经是传值补了,不能再定义传值补。绑定在一起,创建了一个新的可调用对象。绑定在一起,创建了一个新的可调用对象。原创 2023-08-03 15:53:19 · 86 阅读 · 0 评论 -
c++(强生成关键字+可变参数模板+emplace)[26]
默认生成的成员函数会根据类的特性进行生成,例如默认构造函数会生成一个无参构造函数,拷贝构造函数会生成一个按值拷贝的构造函数。强制生成:如果你显式地声明了某个特殊成员函数,但是不提供其定义,编译器将不会生成该函数的默认实现。但是,如果构造函数是私有的,编译器将无法调用该构造函数,从而阻止了在栈上创建对象的方式。是C++标准库容器(如vector、list和deque)提供的一个成员函数,用于在容器的末尾直接构造对象,而不需要显式地调用构造函数。是C++11引入的关键字,用于对类的成员函数进行修饰和控制。原创 2023-07-31 12:20:48 · 102 阅读 · 0 评论 -
c++[左值+右值](25)
通过使用右值引用,可以避免不必要的拷贝构造和析构函数的调用,提高性能。移动赋值(Move Assignment)是C++11引入的一种特性,它允许对象之间的资源转移,而不是进行深拷贝。移动拷贝(Move Copy)是指在C++11中引入的一种特性,它允许通过移动语义来进行对象的拷贝操作。移动拷贝通常用于避免不必要的对象拷贝,提高性能。左值引用只能引用左值,不能引用右值,但是const左值引用既可以引用左值,又可以引用右值。)来实现的,这是C++11引入的一种特性,用于表示临时对象或可以被转移资源的对象。原创 2023-07-30 11:59:53 · 153 阅读 · 0 评论 -
c++学习(c++11)[24]
适用于需要频繁进行插入和删除操作的场景,尤其是在内存占用有限的情况下。因此,我们只能在特定位置之后插入新元素,这在某些场景下可能需要额外的操作来确定插入的位置。是一个单向链表容器,插入操作涉及到修改指针和节点的链接关系,而不仅仅是简单的在容器中插入一个元素。是一个单向链表容器,每个节点只包含一个指向下一个节点的指针,没有指向前一个节点的指针。容器,通常需要手动进行插入操作,而不是依赖于IDE或编辑器提供的右键引入参数插入功能。容器的特性决定了其插入操作的复杂性,无法简单地通过右键点击来自动插入参数。原创 2023-07-29 13:24:54 · 106 阅读 · 0 评论 -
c++学习(布隆过滤器)[23]
在使用布隆过滤器时,需要根据实际情况选择合适的位图长度和哈希函数个数,以平衡空间占用和误判率。布隆过滤器的优点是占用空间小、插入和查询速度快,且不需要存储实际的元素值。但布隆过滤器也存在一定的误判率(False Positive),即可能将不存在的元素误判为存在。查询元素:对于要查询的元素,同样使用k个哈希函数对其进行哈希计算,得到k个哈希值。然后检查位图中对应的位置,如果所有位置都为1,则认为元素可能存在于集合中;插入元素:对于要插入的元素,使用k个哈希函数对其进行哈希计算,得到k个哈希值。原创 2023-07-29 11:20:41 · 221 阅读 · 0 评论 -
c++学习(位图)[22]
位图的主要优点是占用空间小、操作效率高,适用于处理大规模数据和需要高效判断元素是否存在的场景。它使用一个二进制位来表示一个布尔值,其中每个位的值表示对应位置的元素是否存在或满足某种条件。它使用多个哈希函数和位图来表示集合中的元素,可以高效地进行元素的判断。压缩算法:位图可以用于对大规模数据进行压缩,将数据转换为位图表示,从而减少存储空间的占用。位运算:位图可以进行位运算,如与、或、异或等操作,用于实现一些高效的算法和数据结构。去重:可以使用位图来判断某个元素是否已经存在,从而实现去重的功能。原创 2023-07-28 19:54:07 · 141 阅读 · 0 评论 -
c++学习(哈希)[21]
开放地址法(Open Addressing)是一种解决哈希冲突的方法,在发生冲突时,通过一定的规则找到下一个可用的空桶来存储冲突的键值对。闭散列,也称为封闭寻址法(Closed Addressing),是指当发生哈希冲突时,将冲突的键值对存储在哈希表的同一个桶中,通常使用链表或其他数据结构来存储冲突的元素。哈希表的存储方式通常是通过数组来实现的,这个数组通常被称为哈希表或哈希桶。再哈希法(Rehashing):当发生哈希冲突时,使用另一个哈希函数计算出一个新的哈希值,然后将冲突的键值对存储在新的位置上。原创 2023-07-28 19:39:19 · 297 阅读 · 0 评论 -
c++学习(红黑树)[20]
总的来说,红黑树在平衡性和性能之间取得了一种平衡,适用于需要高效的插入和删除操作的场景。红黑树(Red-Black Tree)是一种自平衡的二叉搜索树,它在插入和删除节点时通过一系列的旋转和重新着色操作来保持树的平衡。红黑树的平衡性质使得它在插入、删除和查找等操作上具有较好的性能。在红黑树中,当插入一个节点时,需要通过一系列的旋转和重新着色操作来保持树的平衡。通过上述变色规则,红黑树保持了平衡性质,并且确保了树的黑色节点数量相等,从而保证了红黑树的平衡性。原创 2023-07-22 13:28:16 · 45 阅读 · 0 评论 -
c++学习(avl树)[19]
左旋是将一个节点的右子树变为其父节点,右子树的左子树变为该节点的右子树。右旋是将一个节点的左子树变为其父节点,左子树的右子树变为该节点的左子树。由于AVL树是自平衡的,可以保证树的高度始终保持在O(log n)的范围内,因此插入、删除和查找操作的时间复杂度都是O(log n)。AVL树是一种自平衡的二叉搜索树,它在插入和删除操作后会通过旋转操作来保持树的平衡。AVL树的平衡是通过节点的高度来衡量的,平衡因子是左子树的高度减去右子树的高度。总结:AVL树是一种自平衡的二叉搜索树,通过旋转操作来保持树的平衡。原创 2023-07-21 14:09:40 · 43 阅读 · 0 评论 -
c++学习(map[])[18]
【代码】c++学习(map[])[18]原创 2023-07-20 15:00:05 · 39 阅读 · 0 评论 -
c++学习(set+map)[17]
它基于红黑树(Red-Black Tree)实现,提供了高效的插入、删除和查找操作。它基于红黑树(Red-Black Tree)实现,提供了高效的插入、删除和查找操作。迭代器提供了一种通用的方式来访问容器中的元素,可以通过递增迭代器来遍历容器中的元素,并使用。提供了一系列成员函数来操作和访问容器中的键值对,包括插入、删除、查找、遍历等操作。提供了一系列成员函数来操作和访问容器中的元素,包括插入、删除、查找、遍历等操作。提供了方便的操作接口,适用于需要维护有序且唯一元素集合的场景。根据元素的唯一性和有序性,原创 2023-07-19 19:03:05 · 41 阅读 · 0 评论 -
c++学习(二叉树搜索)[16]
1.什么是多态多态是面向对象编程中的一个重要概念,指的是同一个方法在不同对象上具有不同的行为。简单来说,多态是指一个对象能够根据当前所处的具体类型,来决定调用哪个类的方法。多态可以通过继承和函数重写来实现。当一个子类继承自父类,并重写了父类的方法时,可以通过父类的引用或指针来调用子类的方法。在编译时,编译器会根据引用或指针的静态类型来确定调用哪个类的方法,而在运行时,实际调用的是对象的动态类型所对应的方法。多态的好处是增加了代码的灵活性和可扩展性。原创 2023-07-16 14:24:06 · 35 阅读 · 0 评论 -
c++学习(继承组合+多态)[15]
菱形继承是指在继承关系中存在一个菱形形状的结构,即一个派生类同时继承自两个或多个基类,而这些基类又共同继承自同一个基类。在上述示例中,Platypus类同时继承自Mammal和Bird类,这两个类都继承自Animal类。菱形继承的问题是多继承带来的二义性。由于Platypus类同时继承自Mammal和Bird类,而这两个类都继承自Animal类,所以在Platypus类中存在两个eat。原创 2023-07-14 14:46:05 · 57 阅读 · 0 评论 -
c++(继承)[14]
在单继承中,派生类继承了基类的成员变量和成员函数,并且可以通过派生类对象来访问这些继承的成员。菱形继承是多继承中的一种特殊情况,指的是一个派生类同时继承了两个直接基类,而这两个基类又共同继承自同一个间接基类,形成了一个菱形的继承关系。需要注意的是,静态成员变量的访问权限是在编译时就确定的,所以在继承中,派生类可以访问基类的静态成员变量,即使它们的访问权限是私有的。虚继承通过使用虚基类指针来解决菱形继承的数据冗余和二义性问题,确保只有一份虚基类的实例被派生类继承,并且通过指针来访问虚基类的成员。原创 2023-07-13 14:02:43 · 594 阅读 · 0 评论 -
c++(模板+继承)[13]
在C++中,模板的定义和声明不能分离的原因是模板的实例化需要在编译时进行,而不是在链接时或运行时。模板的定义包含了实际的代码实现,而声明只是告诉编译器有这样一个模板存在。当编译器遇到模板的定义时,它会根据模板参数生成相应的代码,然后将它插入到编译单元中。这意味着模板的定义必须在编译单元中可见,以便编译器可以生成相应的代码。如果允许模板的定义和声明分离,那么在编译时无法生成相应的代码,因为编译器无法确定模板的具体实现。这将导致链接错误或运行时错误。原创 2023-07-12 14:19:24 · 57 阅读 · 0 评论 -
c++学习(非类型模板参数)[12]
需要注意的是,非类型模板参数的特化只能在模板定义的作用域内进行,且特化的定义必须在使用之前。此外,对于非类型模板参数的特化,需要满足特化条件的匹配规则,否则会导致编译错误。总结起来,非类型模板参数的特化是为模板的非类型参数提供具体的值或类型。特化的定义必须在使用之前,并且需要满足特化条件的匹配规则。它提供了类似于C风格数组的功能,同时还提供了更多的操作和安全性。非类型模板参数的特化是指为模板的非类型参数提供具体的值或类型。在C++中,可以通过特化来为非类型模板参数提供具体的值或类型。,并初始化了它的元素。原创 2023-07-11 13:26:10 · 30 阅读 · 0 评论 -
c++学习(priority queue)[11]
总结起来,priority queue是一种按照优先级进行插入和删除操作的特殊队列。它可以使用二叉堆或斐波那契堆来实现,具有快速的插入和删除操作。优先队列在任务调度、模拟系统和数据压缩等场景中有广泛的应用。在斐波那契堆中,数字表示节点的值,箭头表示节点之间的关系,横线表示子堆之间的关系。例如,节点13指向节点11,节点11和节点12之间有一条横线连接。是一种特殊的队列,其中每个元素都有一个与之关联的优先级。在优先队列中,元素按照优先级的顺序进行插入和删除操作,优先级高的元素先被处理。原创 2023-07-10 17:30:54 · 50 阅读 · 0 评论 -
c++学习(栈和对列)[10]
在C++中,std::stack和std::queue是两个常用的容器适配器,它们提供了栈(先进后出)和队列(先进先出)的功能,是基于std::deque或std::list等容器实现的。原创 2023-07-10 16:47:31 · 36 阅读 · 0 评论 -
c++学习(list)[9]
T _data;//存放数据 list_node < T > * _next;//指向下一个结点 list_node < T > * _prev;//指向前一个结点 list_node(const T & x = T()) //构造函数 : _data(x) , _next(nullptr) , _prev(nullptr) {} };typedef;public :list() {//头结点 };原创 2023-07-08 16:57:04 · 210 阅读 · 0 评论 -
c++学习(vector--迭代器失效)[8]
在C++中,迭代器失效是指在对容器进行修改(插入、删除等)后,之前获取的迭代器可能会变得无效,不能再使用或者指向错误的元素。在使用特定容器的迭代器时,应该查阅相关文档或参考C++标准来了解该容器的迭代器失效规则,并遵循相应的注意事项来避免迭代器失效问题。重新获取迭代器:在对容器进行修改后,如果需要继续使用迭代器,应该重新获取迭代器,而不是继续使用之前的迭代器。使用插入函数返回的迭代器:在插入元素时,使用插入函数返回的迭代器来获取插入后的位置,而不是之前的迭代器。函数来获取容器的起始和结束迭代器。原创 2023-07-05 14:38:42 · 86 阅读 · 0 评论 -
c++学习(vector)[7]
拷贝一个数据时1.析构两次2.对一个对象进行修改会影响到另一个对象解决方案1.增加一个引用计数,每个对象析构时–进行引用计数,最后一个析构的对象释放空间2.写时拷贝(延迟拷贝,谁去写,谁做深拷贝,没有发生写入时很赚)原创 2023-07-04 22:04:13 · 209 阅读 · 0 评论 -
C++学习(模板string类)[6]
std::string是一个字符串类模板,定义在头文件中。它是C++标准库中提供的用于操作字符串的模板类。std::string模板类提供了一系列成员函数和操作符重载,用于对字符串进行各种操作,例如字符串的拼接、查找、替换、插入、删除等。以下是一些常用的std::string成员函数和操作符重载:length() 或 size():返回字符串的长度。empty():检查字符串是否为空。clear():清空字符串。c_str():返回一个以null结尾的C风格字符串。原创 2023-07-01 11:18:57 · 251 阅读 · 0 评论 -
C++学习(模板)[5]
编译器在使用模板前要经过 模板参数推演–函数模板–推演参数实例化函数模板的定义通常以关键字template开始,后面跟着模板参数列表和函数定义。模板参数列表中可以包含类型参数、非类型参数和模板参数包等。int实际是生成了不同的实例化函数。原创 2023-06-29 22:44:05 · 44 阅读 · 1 评论 -
C++学习(申请内存)[4]
程序内存区域划分为:内核空间(用户不能读写)、栈(向下增长)、内存映射段(文件映射、动态库、匿名映射)、堆(向上增长)、数据段(全局数据、静态数据)、代码段(可执行代码/只读常量)。在申请空间时,针对内置类型,new/delete和malloc/free没有本质的区别,只有用法的区别new/delete用法简化,是为自定义类型准备的,不仅在对申请出来,还会调用构造和析构初始化清理。**注:**new/delete和new[]/delete[]一定匹配使用,不然可能会出错(在堆上申请)原创 2023-06-29 22:25:12 · 674 阅读 · 1 评论 -
初识类(1)
类中的成员变量只是声明,没有分配存储空间,未进行实例化。之所以能够计算大小原理相当于有房子的图纸就能知道房子可以容纳多少人。原创 2023-05-16 21:55:32 · 30 阅读 · 0 评论 -
内联函数/auto(c++)
以inline修饰的函数被称作内联函数,编译时c++编译器会在调用内联函数的地方展开,没有函数压栈的开销,可以提升程序运行的效率。2.protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)﹑只能在类里面访问。注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别。1.public修饰的成员在类外可以直接被访问也能在类里面访问。inline具有宏定义的优点,解决了宏定义的缺点。c++在定义的第一行即生成。原创 2023-05-15 10:41:04 · 35 阅读 · 0 评论 -
类的默认函数
一般的类不会让编译器默认生成构造函数,会自己写。显性写一个全缺省。只有在特殊情况下才会使用默认生成的函数。原创 2023-05-21 18:48:42 · 31 阅读 · 0 评论 -
C++函数重载和引用
编译器在编译.c文件时,只会给函数进行简单的重命名。所以加入两个函数名相同的函数在编译之后的函数名也照样相同;调用者会因为不知道到底调用那个而出错;cpp中两个函数的函数名一样,但是他们在符号表中生成的名称不一样。在一个作用域中可以声明几个名字相同功能类似的函数。这些同名函数的参数个数、类型、顺序要不同。多态分为:静态多态(运行时)和动态多态(编译时),函数重载是一种静态多态。重载函数的参数个数,参数类型或参数顺序三者中必须有一个不同!一个程序要能够被执行需要经过:预处理–编译–汇编–链接。原创 2023-05-01 22:07:28 · 41 阅读 · 0 评论