- 博客(48)
- 收藏
- 关注
原创 C++泛型编程
泛型编程主要使用模板来实现。模板就是允许你编写与类型无关的代码,即对所有传入的数据类型编写通用的实现代码。比如,我想返回传入数据的占内存大小。对这个问题的解决,可以不依赖数据类型,我们都可以通过相同的操作返回结果。函数模板的定义如下代码:注意:每个函数模板都要在其之前使用template<>声明,不可复用。// 指定一个参数类型的函数模板// 指定多个参数类型的函数模板//指定可变参数函数模板模板定义的语法不用多说,但是模板参数有很多知识点需要掌握。类模板的定义形式和函数模板没有太大区别。
2024-11-02 22:39:24
924
原创 C++智能指针的实现
RAII(Resource Acquisition Is Initialization)是一种资源管理技术,常用于 C++ 编程中。其核心理念是将资源的获取和释放与对象的生命周期绑定在一起。这样,资源的管理(如内存、文件句柄、网络连接等)可以通过对象的构造和析构来自动化,确保资源不会泄漏。RAII 的基本原则当一个对象被创建时(即构造函数被调用),它会获取所需的资源。这可以是动态分配的内存、打开的文件、网络连接等。资源释放当对象的生命周期结束时(即析构函数被调用),它会自动释放所获取的资源。
2024-11-01 00:47:51
794
原创 C++类成员函数声明修饰符总结
函数声明时,末尾添加表示此函数被禁用,通常用于禁用复制构造函数、赋值运算符等特定函数。使用方法如下用于知识编译器生成默认的构造函数、拷贝构造函数、赋值运算符等特定函数例如如下代码,表示默认构造函数和拷贝构造函数都被使用,且使用编译器默认的定义(这样我们就不需要写定义了)表示此函数是重写了基类中的虚函数,有助于编译器检查是否完成重写。如果编译器在编译时检查到此函数在基类中没有找到匹配的虚函数,则编译器会报错。用于指示一个虚函数不能被重写,或者一个类不能被继承。
2024-10-13 22:38:25
424
原创 C++智能指针
std::unique_ptr可以使用自定义删除器,以支持不同的资源释放策略。通俗的说,有的资源只让unique_ptr自动调用delete或者delete[] 无法完全释放。这时,我们可以自定义释放策略,传给unique_ptr,让其释放资源的时候自动执行。unique_ptr支持传入函数指针和函数对象作为删除器。注意,make_unique不支持自定义删除器的使用,所以。
2024-07-31 02:04:25
942
原创 C++11并发编程
本篇文章主要介绍在C++中如何实现基本的并发编程。介绍了C++11、14、17的相关C++特性。面向对并发和多线程有些基本了解,但是不知如何使用C++新特性去实现并发编程的小伙伴们。本篇文章对这类疑问起到一个入门的参考作用,相关函数和类可能介绍的不是十分全面,但是基本用法都有说明,如果想要了解更多,可以参考C++标准库官方文档等资料。
2024-07-26 18:05:29
1035
原创 STL常用容器及使用总结
上述介绍的八种关联容器可以分为两类集合(set)和映射(map)。其中set的无序版本是unordered_set,键值可重复版本是multset,无序且键值可重复版本是unordered_multset。map的无序版本是unordered_map,键值可重复版本是multmap,无序且键值可重复版本是unordered_multmap。
2024-07-15 15:24:59
1324
原创 完全二叉树、搜索二叉树、平衡二叉树和满二叉树(C++)
完全二叉树是这样定义的:若二叉树的深度为 h,除第 h 层外,其它各层的结点数都达到最大个数,第 h 层所有的叶子结点都连续集中在最左边,这就是完全二叉树。(第 h 层可能包含 [1~2h] 个节点)上面的定义看起来比较复杂。所有节点只存在3种情况:1、有左右2个孩子;2、只有左孩子;3、没有孩子(叶节点),即不存在只有右孩子的情况;我们采用层序遍历的方式遍历节点,当遍历到某一个节点,它只有左孩子,或者没有孩子,则后序所有节点一定都是叶节点。如下所示是完全二叉树节点的左子树只包含小于当前节点的数。
2024-05-21 16:59:32
8547
原创 C++内联命名空间和嵌套命名空间简化语法
首先,我们简单回顾下命名空间的作用。在开发一个大型项目过程中,会有很多开发人员参与开发,也会引入很多第三方库,项目代码引用了同名的类和函数无法避免。这个时候使用命名空间来区分不同的类和函数就可以解决冲突的问题。例如C++11提出了内联命名空间的概念。被声明为内联的命名空间,可以将其所有成员导出到父命名空间。使用一个例子具体说明:将上述v2改为内联命名空间,即在v2之前添加inline声明即可,其他不用修改这样修改之后,使用v2中成员的时候就可以不用再指定v2命名空间了。
2023-06-24 17:33:54
639
原创 c++ auto学习笔记
在C++11中赋予auto的意义是:在声明变量时,根据初始化表达式自动推断该变量的类型。声明函数时作为函数返回值的占位符(用在函数返回类型后置的情况)。如。
2023-06-24 16:05:31
984
原创 C++万能引用和完美转发
有的时候我们需要既能引用左值,又能引用右值的情况。并且不想使用常量左值引用(既能引用左值,又能引用右值),因为其具有常量性。这时,我们就需要实现一个万能引用即可。请见如下2组例子上面代码中m和x为右值引用毋庸置疑,而非常相似的n和y都是万能引用。因为在推导过程中,如果初始化的对象是左值,则其被推导为左值引用;初始化的对象是右值,则其被推导为右值引用。万能引用能够实现上诉的工作,是因为应用到了引用折叠。
2023-05-05 21:58:59
564
原创 python基础-python编程基础
print函数的基本语法是 print(需要输出的内容),内容可以是数字、字符串、变量、表达式等见代码从上可见,print会自动换行。如果想在一行连续输出多个内容,可以加“,“;如果想使用多个print语句输出一行内容,可以使用在print函数添加end=参数。还可以使用print函数进行格式化输出。
2023-02-18 13:25:21
109
原创 C++ lambda表达式
lambda表达式又叫匿名函数。是现代C++的一种语法糖,并且仍在持续更新。lambda表达式是在调用或作为参数传递的函数的位置处定义匿名函数对象的便捷方法。lambda表达式的一般 形式如下如果使用上述的方式定义一个匿名函数,则此匿名函数只有一次调用机会,即在定义的时候就进行了调用:();但是一般情况下,我们可以使用一个auto 类型变量来接受这样一个匿名函数对象,这样我们可以在更合适的位置进行调用,也可以进行多次调用,更加方便。见如下形式。
2022-09-04 14:05:16
3015
原创 C++ new和malloc的区别
事实上,自由存储区是C++为new操作符抽象出的概念,使用new分配出的区域就是自由存储区。而在物理意义的内存上,自由存储区可以在堆也可以在其他地方(比如静态存储区),这取决于编译器从哪里为new的使用分配内存。从上面的实例中,我们就可以注意到malloc返回的指针还需要进行强制类型转换才赋值给A*的指针对象,而使用new则不需要,直接返回的是A*的指针。我们知道内存分为代码区、常量存储区、静态存储区(全局存储区)、堆区、栈区(关于内存分区可以见下面的文章)。使用new是类型安全的。...
2022-07-28 22:40:53
6440
4
原创 C++几种常见的数据结构
由于vector是顺序存储结构,所以如果发生了扩容,需要重新申请一块更大的连续内存空间,并将原数据复制过去,所以存储地址有可能发生变化。顺序表相邻(逻辑地址相邻)的两个节点,在内存中具有相邻的物理地址。线性表存储的数据是依次排列的,具有一对一的相连方式。链表相邻(逻辑地址相邻)的两个节点,在内存中的物理地址不一定相同。的对应关系的数据存储结构。如下图所示是我们比较常用的二叉树结构,二叉树具有1对2的对应关系。栈和队列是特殊的线性表,因为他们对数据的进出顺序做出了明确的要求。的对应关系的数据存储结构。...
2022-07-27 22:47:10
9475
1
原创 二叉树的先序、中序、后序遍历C++
先遍历根(父)节点、再遍历左节点、最后遍历右节点。注意这里说的遍历并不是行走。毕竟我们能够先取到的指针只有根节点指针,而如果想找一个节点,则一定要先找到它的根节点。这里的遍历指的是“介绍”这棵树的方式。通常来讲,我们是使用的打印的方式“介绍”一棵树的。所以,先序遍历展开来讲是如果一棵树上有根节点,则先输出根节点,再输出左孩子节点、最后输出右孩子节点。例如,上述图1中的二叉树,先序遍历输出是先遍历输出左孩子节点,再遍历输出根节点,最后遍历输出右孩子节点。例如,上述图1中的二叉树,中序遍历输出是。...
2022-07-24 21:52:18
30941
原创 设计模式-外观模式C++
外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。我们可以将这个类看作是复杂系统的外观,对客户端提供调用系统实现某种功能的接口,而如何调用(对系统接口的调用顺序和调用依赖)不对客户端展示,由外观类自己处理。我们知道新生入学是十分麻烦的事情,需要办理各种手续,甚至可以让学生和家长忙碌一整天
2022-07-13 22:52:17
236
原创 单链表相交问题C++
给定两个可能有环也可能无环的单链表,头节点head1和和head2。请实现一个函数,如果两个链表相交,请返回相交的第一个节点。如果不想交,返回null基于这两个链表分别可能有环和无环,基于单链表只能存在一个next指针的特性,我们分成3中情况讨论:则两个链表想要相交,则一定是如下这种形态即两个链表从某个节点开始,存在公共部分,公共部分的第一个节点则为相交节点。由于单链表只能有一个next节点,有环链表的环一定在尾部,而结尾不同的两个链表是无法相交的。所以可以得出结论,不存在这样情况下的相交链表。则两个链表想
2022-07-12 21:38:08
521
原创 【题目】复制含有随机指针节点的链表C++
一种特殊的单链表,节点结构如下所示除了next指针外还具有一个随机指向的rand指针,rand指针可能指向链表中的任一节点,也可能为null。给定一个由Node组成的无环单链表的头节点head,请实现一个函数完成对该链表的复制。要求:时间复杂度O(N),额外空间复杂度O(1)如果不要求额外空间复杂度,我们可以开辟一个map来保存新旧节点的对应关系,然后连接新链表。代码如下【测试用例参考】但是题目中要求空间复杂度为O(1),此算法的额外空间复杂度为O(N),不满足要求。为什么要设置此对照组?
2022-07-09 21:43:59
392
原创 C++内存分区管理
一、内存分区模型代码区:存放函数体的二进制代码,有操作系统进行管理全局区:存放全局变量、静态变量和常量栈区:由编译期自动分配释放,存放函数的参数值、局部变量等堆区:由程序员分配和释放,若程序员没有释放,程序结束后由操作系统回收内存四区的意义:不同区域存放不同数据,赋予不同的生命周期............
2022-07-09 16:18:24
859
1
原创 设计模式-组合模式C++
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。 上图中的对象组:红色的对象是包含其他的对象组的对象,在树状结构中,为非叶子节点黑色的对象是不再包含其他对象组的对象,在树状结构中,为叶子节点组合模式创建了一个可以包含自己对象组的类。该类提供了修改或查询相同对象组的方式。上述描述可能比较抽象, 我们使用生活中的一个例子说明:(可以结合
2022-07-08 22:31:01
498
原创 设计模式-过滤器模式C++
过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准。假如某地政府为了帮助无业人员就业,统计了一批36岁市民的就业情况。政府拿到名单后,过滤出无业人员帮助就业。为了完成这个项目,我们需要建造:1)人员信息类 Person;2)标准抽象类 Criteria,提供按照某标准过滤的接口 meetCriteria;
2022-07-03 22:21:13
861
原创 链表-快慢指针(C++)
链表是由一组在内存中不必相连(不必相连:可以连续也可以不连续)的内存结构Node,按特定的顺序链接在一起的抽象数据类型。我们常见的链表结构有单链表和双向链表。单链表,保存了下一个结点的指针,可以根据下一结点指针向下遍历双向链表,保存了向上一个结点和向下一个结点的指针,所以可以向上下两个方向遍历。单链表结构一般如下:双向链表的结构一般如下:在算法中,我们遇到的链表题目一般可以使用一些经典的思路求解。本篇博客主要讨论这些经典的链表解题思路之一,快慢指针。快慢指针也称龟兔赛跑算法,又叫判圈算法。具体方
2022-06-26 18:39:51
1841
原创 设计模式-桥接模式 C++
一、简介1、什么是桥接模式桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。2、使用桥接模式解决什么问题声明抽象类和抽象类的实现类,使用桥接模式使二者直接都可以独立变化,达到解耦的目的。...
2022-04-22 16:36:13
1019
原创 设计模式-装饰器模式 C++
一、简介1、什么是装饰器模式装饰器模式是结构型设计模式。装饰器是现有类的一个包装,可以在不修改现有类且不增加子类的情况下扩展现有类。【注】可以实现向一个现有对象添加新的功能,同时又不改变其结构的设计模式,称为结构型模式。2、为什么使用装饰器模式装饰器模式用于需要对现有类进行扩展的场景。一般情况下,我们想要扩展现有类还可以声明它的子类,即使用继承的特性达到目的。但是如果我们经常使用增加子类的方法扩展现有类,会造成子类的臃肿膨胀。...
2022-04-21 17:10:11
1286
原创 设计模式-适配器模式 C++
一、简介1、什么是适配器模式适配器模式属于结构型模式。适配器作为两个接口之间的桥梁,用于适配两个不兼容的两个接口。适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。2、适配器模式用于解决什么问题在工程中,可能要将现存的类A放到新的环境中,而新环境要求的接口B是现对象不能满足的。我们在无法改变A和B的情况下可以增加一个适配器类C,C调用现存的类对象A实现B的某些功能。达到用A实现了B的接口的效果。4、使用适配器模式的注意
2022-04-20 15:05:57
692
原创 基数排序的词频表方法
基数排序是非比较排序方法中比较重要的排序。一般情况下,我们都是基于FIFO桶对其实现。基于桶的方法见下面文章:(2条消息) C++实现排序算法_星星典典的博客-优快云博客https://blog.youkuaiyun.com/ymhdt/article/details/123293536本文采用另外一种方式,基于词频表的实现。这里说的词频表可以理解为在数组中某一类数字出现的次数。在基数排序中,我们定义一张表,使用count数组作为容器,用于记录数组 “某位置...
2022-04-17 15:01:12
194
原创 C++实现排序算法
一、冒泡排序上浮法 :从数组末尾开始,连续比较相邻两个元素,使其符合排序。比较一个循环后,处于数组前排的元素最先符合(最大 or 最小),不再参与下一个循环的比较。下沉法:从数组开头开始,连续比较相邻两个元素,使其符合排序。比较一个循环后,处于数组后排的元素最先符合(最大 or 最小),不再参与下一个循环的比较。冒泡法最优时间复杂度可以达到O(n),最差可以达到O(n^2)【注】如果上一次循环已经符合排序,即没有交换过一次,则已经排序完成,得到结果,不需要再进行下一次循环参考代码 C+.
2022-04-12 13:39:41
11827
原创 设计模式-观察者模式 C++
一、简介观察者模式属于行为型模式。意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。二、建立和使用观察者模式1、建立观察者组件首先,我们有一个被观察的对象A,和观察对象A的观察者对象B、C、D。则我们需要1)、声明一个抽象观察者类,类中声明观察者响应函数;2)、被观察对象A需要一个成员数据,观察者对象的指针列表_observer
2022-04-08 15:35:33
944
原创 const的使用总结-C++
一、const修饰指针二、const在传入参数中的应用更改 *p = 30 错误三、const修饰函数返回值四、const修饰类成员变量五、const修饰对象六、const修饰类成员变量
2022-04-07 16:08:36
791
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人