C++
文章平均质量分 89
起床写代码啦!
一个菜鸡
展开
-
C++(18)——适配器概念以及stack、queue、优先队列的模拟实现
在对的相关实现原理进行介绍前,首先来总结之前介绍的两种容器:的优缺点:对于,在前面对其进行模拟实现的文章中提到,可以将看作之前数据结构中的顺序表,其特点是存储空间在物理以及逻辑上的连续性。因此,借由连续性可以得出,的优点在于通过下标可以对空间中的内容进行随机访问。并且缓存命中较高对于其缺点,则是头部或者中间进行插入、删除元素时的效率过低,以及一次性开辟较多空间时带来的损耗对于,同样提到,可以将其看作成带哨兵位头结点的双向循环链表,其特点是存储空间在逻辑上连续,但是在物理上不连续。原创 2024-02-20 22:13:17 · 913 阅读 · 0 评论 -
C++(17.5)——list模拟实现扩展
在上篇文章中,实现了的大部分功能以及部分迭代器。本片文章将对剩下的功能进行补充。对于上篇文章中实现的迭代器只能使用于非类型的对象。对于类型的遍历,则需要额外编写类型的迭代器。对于与非类型的变量的区别,是类型的对象不能修改。因此,实现迭代器的第一种方法,便是将非迭代器的相关代码进行复制然后进行改动,基于类型本身的性质,只需要将函数的返回值类型改为在完成上述步骤后,还需要在中,引入__,并且为了方便书写,利用函数将其改写为。原创 2024-02-01 21:48:18 · 821 阅读 · 1 评论 -
C++(17)——list的模拟实现
需要注意的是,在定义链表的起始时,并不能定义成哨兵位头结点,因为哨兵位头结点并没有保存数据,在访问链表时,需要从第一个保存数据的结点开始访问。这个自定义类型,而是这个类型的指针,而指针是一个内置类型,因此,不能直接完成对于指针的重载。的结构可以近似的看为链表,由于链表的空间不连续,因此,在使用迭代器进行访问时,对迭代器。在删除任意位置的结点前,首先需要找到这个结点的前结点和后结点的地址,为了方便表达,用。中,由于这两种数据结构的空间是连续的,因此,在实现其迭代器功能时,通常先利用。获取下一个结点的地址。原创 2024-02-01 16:10:54 · 2037 阅读 · 0 评论 -
C++(16)——vector的模拟实现
前面的文章中,给出了对于的模拟实现,本篇文章将给出关于的模拟实现。对于类,主要是针对于字符型变量这一种数据类型,但是对于,要同时适用于不同的数据类型,对于这一点,可以利用之前中的模板参数来实现。在中的源代码中,类中的成员变量分别为。三个变量的类型都是迭代器。其中表示开头,表示已有内容的结尾,表示开辟空间的结尾。通过上述信息,可以给出对于的构造函数,直接初始化为即可。因为三个成员变量的类型是由内置类型经过后的。原创 2024-01-29 01:40:47 · 905 阅读 · 1 评论 -
C++(15)——vector
中同样可以使用迭代器对内容进行访问,这一部分内容将在下面介绍迭代器的部分统一给出。会通过向容器的末端插入元素的方式来达到扩容的目的,并且会同时改变容器的。对于二者的差距,表现为是否可以修改迭代器指向的内容,例如,对于非。函数的构造是利用迭代器进行构造的。并且,如果不人为给出扩容时插入的元素,则默认插入。虽然都可以达到改变容量的效果,但是却又一定的差别。,但是会影响容器中的内容,以及容器的。的相关函数,以及部分函数的使用方法。函数的作用,此处先引入一个新的函数。其作用可以看作顺序表中的尾插。原创 2024-01-25 14:11:57 · 962 阅读 · 0 评论 -
C++(14.5)——再谈拷贝构造与深浅拷贝
上篇文章中,通过模拟的方式完成了类对象中常用的函数。在本篇文章中,将通过一个例子来进一步说明拷贝构造与深浅拷贝。注:本文需要使用上一篇文章中模拟实现关于类的函数上述代码的目的是将中存储的网址进行分隔。但是当运行代码时,编译器会显示错误:对于通过上述代码,不难得出其整体逻辑为:函数返回类型的对象作为右操作数用来给赋值。由于函数的返回值不是引用返回,所以,函数并没有返回本身,而是返回的一个临时拷贝,为了方便描述,这里命名为。原创 2024-01-23 15:53:50 · 934 阅读 · 2 评论 -
C++(14)——string的模拟实现
在介绍引用时,提到,引用返回相对于指针返回有两个有点,一是速度更快,二是可以修改返回值。中提到了初始化列表的概念,但是从上出给出的三个成员变量不难看出,三个变量全是内置类型,因此,对于内置类型的初始化,直接在函数内部进行,由于。以及其相关函数的使用,为了更清楚的了解这些函数的作用,本篇文章通过模拟实现的方式来加深对于函数作用原理的理解。对于第一组变量,通过前面对于模板的了解得知其会去自动调用模板函数,对于第二组变量,在没有第一、二种。对于第一种情况的删除,并不需要真正的将字符一个一个进行删除,只需要将。原创 2024-01-20 23:12:34 · 939 阅读 · 1 评论 -
C++(13)——string
类型的对象或者字符串或者字符,在不给定参数的情况下,在给定的上述三个类型中,从另一个。此函数的使用方法与上一小节中的方法相同,只是参数的类型发生了改变,故不再赘述。函数的两个参数如上述代码所示,此函数的主要作用是根据一个已有的。find_first_of函数,其大体意义如下:给定一个。如果需要将上述对象中所有在字符串中出现的字母,即。类型的对象的内容分离,在进行分离时,常常会和。主要用于对一个已有的。为范围内的内容生成一个新的。类型的对象进行分隔。类型的对象出现时替换为。例如:给定一个字符串。原创 2024-01-17 22:08:21 · 498 阅读 · 0 评论 -
C++(12)——string
上篇文章中,介绍了中一些函数的应用。本篇文章将介绍其他中相关函数的应用。对于本部分标题中的函数,其作用为在已有类型的对象的第个位置插入另一个对于本部分标题中的函数,其作用为在已有类型的对象的第运行结果如下:对于本部分标题中的函数,其作用为在已有类型的对象的第个位置插入另一个另一个常量字符串的前运行结果如下:对于本部分标题中的函数,其作用为在已有类型的对象的第个位置插入个连续的字符。例如在一个类型的对象的第个位置插入两个连续的字符运行结果如下:此外,本函数经常用做在。原创 2024-01-17 19:31:19 · 957 阅读 · 0 评论 -
C++(11)——string
文章将对上述图片中某几个常用的函数进行介绍,其他函数的使用方法可以通过上方网址进行查阅。对于二者的不同点,可以认为第一种可读可写,但是第二种只能读。,是用于反应这个对象中字符串的长度的。进行扩容时,扩容后的大小并不一定等于预设的值,通常会大于这个值。的大小只和该类型能够存储多少内容有关,与对象中是否有内容无关。只能改变空间,并不能影响对象中的内容。类对象进行缩容时,并不能缩小到这个对象的最小容量。上面说到,对于第一种方式,不光可读,而且可写,因此,让。进行扩容后,发现,此时扩充的部分的值全部为。原创 2024-01-15 16:46:46 · 895 阅读 · 1 评论 -
C++(10)——模板
在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此。而对于本篇文章的主题模板,便是泛式编程的基础。但是这种做法同样存在缺点,即只能针对一种单一的类型,如果需要存储两种不同类型的数据,则需要将上述代码进行一次复制,再改写。的类型的过程称之为模板的推演,把推演后,编写函数的过程称之为模板实例化。原创 2024-01-13 01:18:32 · 1086 阅读 · 0 评论 -
C++(9.5)——浅谈new和delete的实现原理
此处可以看出来,针对自定义类型,在释放空间时,并不能区调用。时就提到,当成功的开辟空间后,返回值会返回这块空间的起始地址。不难发现,两个全局函数只能开辟空间,并不能像操作符一样调用构造函数或者析构函数。针对自定义类型会去调用自定义类型的构造函数,在构造函数中,再开辟一次空间。中,面向对象的编程并不能在失败用返回值进行处理,而是需要抛异常,对。对于这两个关键字开辟空间或者释放空间的功能的原理,是借助。一样释放掉开辟的空间,而是释放掉空间中的资源,也就是指针变量。开辟空间,调用构造函数对空间进行初始化。原创 2024-01-12 22:21:48 · 1347 阅读 · 0 评论 -
C++(9)——内存管理
在上面的使用方法中,同样无法完成对于开辟空间的初始化。如果想初始化开辟的空间,例如将开辟的一个类型为。等函数完成的,在数据结构中,经常在创建一个关于数据结构的单个结点时使用。但是,这些函数针对于自定义类型并不能解决初始化的问题。来完成开辟自定义类型空间时的初始化问题。,其动作过程也可以分为两步: 调用自定义类型的析构函数、释放空间。,只能开辟空间,并不能对开辟的空间进行初始化。通过结果可以得知,在开辟空间时调用了自定义类型。在C语言中,对于内存的管理通常是使用。不难发现,在上述代码中,开辟了。原创 2024-01-12 17:22:59 · 1089 阅读 · 0 评论 -
C++类与对象基础(8)
在之前关于流插入、流提取这两个运算符进行运算符重载的时候就提到过,由于这两个运算符在重载时,需要保证两个参数的顺序,因此,需要把此运算符重载作为全局函数而非成员函数,但是,成员函数在类中访问限定符为私有的情况下,全局函数不能访问成员变量,因此,需要采用友元的方式,让全局函数可以访问成员变量。3.比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问 Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。原创 2024-01-10 22:05:01 · 789 阅读 · 0 评论 -
C++类与对象基础(7)
初始化列表,static成员以及static函数原创 2024-01-10 15:33:10 · 774 阅读 · 0 评论 -
C++类与对象基础(6)
取地址操作符重载是默认构造函数,他的性质与构造函数类似,当不人为编写上述两个重载时,编译器会自动生成,当认为编写两个重载时,编译器会去调用已经编写好的。这是因为,对于双操作数的运算符,第一个参数是左操作数,第二个参数是右操作数,之前的文章中多次提到,对于成员函数来说,通常会有一个隐藏的参数,即。,为了避免此问题,可以将运算符重载的声明放在类之外,即作为一个全局函数,而非一个成员函数。需要注意的时,这两个函数不光类型不同,其参数类型也不同,对于。可以正常运行的原因。封装在一个类的成员函数中,进行调用的。原创 2024-01-08 22:29:14 · 980 阅读 · 0 评论 -
C++类与对象基础(5)——日期类的实现
【代码】C++类与对象基础(5)——日期类的实现。原创 2024-01-08 16:06:52 · 730 阅读 · 0 评论 -
C++基础(4)——类与对象(默认成员函数)
由于C++规定自定义类型传值或者值拷贝需要调用拷贝构造,因此在第一次传参后,并没有直接去调用拷贝构造,而是编译器额外新生成一个拷贝构造函数,并且去调用新生成的拷贝构造函。通过对上述日期类和栈类的调用,会发现,在日期类进行传值调用或者说进行浅拷贝时,并不会出现错误,而对于栈这个类则会报错。函数时,首先需要传递参数,此时传递参数的方式为传值拷贝,因为,会调用拷贝构造函数,由于拷贝构造函数的参数是类型对象的引用,因此参数。上面提到,两个对象中的指针指向了同一块空间,因此,本次清理时,会造成错误,原创 2023-11-23 20:21:26 · 939 阅读 · 0 评论 -
C++基础(2)——类和对象
这是因为,在每次调用时,类中的变量都会接收不同的值,而函数除了传递的形式参数没有任何变化,因此,在类中,变量是独立存储的,而函数,则是在一个公共空间中存储的。从上面给出的代码不难看出,利用C++对栈的相关代码进行改写时,不但让函数中的参数数量减少,并且还化简了C语言中与栈相关的功能函数的函数名。而在C++中,因为类的作用域(对于类的作用域将在文章后部给予相关解释,本处只是提出这个概念关系,并且可以在类中定义函数,因此,可以在不同的类中,同时定义。因此,对于上述无成员变量的类的对象(a),大小为1字节。原创 2023-11-12 22:15:15 · 439 阅读 · 0 评论 -
C++基础——对于C语言缺点的补充(2)
这是因为在这种返回类型下,返回值并不能确定,如果编译器在函数结束后直接清理掉栈帧,则返回空,如果编译器在函数结束后,并不会立即清理掉栈帧,则返回还能有返回值。运行程序,编译器会报错。这是因为在存在一个不含参数的函数与另一个有参数,且参数有缺省值的情况下,同时运行两个函数会造成二义性,即:编译器不能判断在。运行此代码时,并没有错误,不难观察到,上下的给的代码唯一的差距就是第二次给出的代码的引用前加了。,但是这两个函数的返回值类型,以及参数类型都不同,此时符合上方函数重载的定义,构成了函数重载。原创 2023-11-06 20:53:11 · 417 阅读 · 0 评论 -
C++基础——对于C语言缺点的补充(1)
在了解了命名空间冲突这一概念后,会发现,在C语言中,当需要定义的变量数量较多时,容易发生命名空间冲突这样的错误,在C语言中,也并没有提供解决命名空间冲突这一问题的方法。输入、输出这两个功能在日常的测试中使用频率很高,不采用命名空间展开,在使用时,使用方法较为繁琐,但是展开命名空间并不一定安全,为了解决上面的两个问题,引出在命名空间这一章节中说到,命名空间的展开存在一种部分展开的方式。虽然命名空间的展开可以达到简化访问命名空间中变量的作用,但是,并不能轻易展开命名空间,例如C++中自带的命名空间。原创 2023-11-04 23:19:26 · 190 阅读 · 0 评论