C++
文章平均质量分 96
C++语言的学习
KissKernel
不秃就好
展开
-
C++多态机制详解(多态实现原理,单继承和多继承时虚函数表,菱形继承时的虚函数表原理)
多态就是多种形态。就是不同对象在完成同一种行为的时候结果不同。一种情况是不同的对象,调用同一个函数,但是出现了不同的结果。1.静态多态:函数重载(看起来调用的是一个函数但是传递不同的参数有不同的行为,比如cout的自动识别类型)2.动态多态:用一个基类对象的引用或者指针去调用重写完成的虚函数,更具引用或指向的对象不同,出现不同的行为静态:是指在编译阶段实现动态:是指在程序运行阶段实现被virtual修饰的函数就是虚函数public:这里的func1就是虚函数。原创 2024-03-23 17:56:04 · 609 阅读 · 0 评论 -
C++继承机制详解(单继承,多继承,菱形继承,虚继承)
继承的核心是代码的复用,继承机制就是面向对象语言对于类保持原来的结构,并对其进行扩展的重要手段。在继承里有这样两个类,基类(父类),派生类(子类)。继承就是子类继承父类,子类的结构相当于是在父类的结构上面的一个扩展。继承是类在设计层次的复用。继承可以说是C++语法复杂的一个方面,因为有了多继承,所以就会存在菱形继承,为了解决菱形继承又有了菱形虚拟继承。不仅底层实现复杂,对性能也有影响。所以一般不能设计出菱形继承。大多数情况都是使用单继承。像是java只有单继承。原创 2024-03-22 10:42:28 · 711 阅读 · 0 评论 -
模板高级使用(非类型模板参数,特化,分离编译)
如果基础的模板参数带有const,比如上面代码通用模板的类型时const T&,我们特化出来的类型目的是将T替换,但是这时候特化后的T应该写在cosnt &的前面不然就会报错。使用模板可以让编译器替我们完成一些重复的工作,同时也可忽略类型,让我们只关注代码逻辑的本身,但是有些特殊情况模板的默认处理逻辑并不能完成我们的需要,这时候就有了模板的特化。如上这里的第二个模板参数就是一个常量,但是非类型模板参数只能是int类型的常量,其他比如:double,字符串或者自定义类型变量那么都是不行的。原创 2024-03-21 22:44:11 · 636 阅读 · 0 评论 -
STL_list文档使用介绍与底层代码实现简介
在STL中list底层使用的是双向带头循环链表,这是一个很完善的结构,可以做到在O(1)时间内完成pos位置的插入删除。唯一的缺点是不支持随机访问,如果要访问list中的第三个元素,只能通过遍历迭代器或者范围for来访问第三个元素。所以list不支持算法库里面的sort(因为算法库中的sort底层是快速排序,快速排序为了防止最坏的情况也就是已排序好的数据,在这种情况下的效率就是O(N^2)因此引入了三数取中,但是如果不支持随机访问,三数取中就不可以使用了)原创 2024-03-20 14:59:05 · 815 阅读 · 0 评论 -
STL_vector简化模拟—详解深层次深拷贝问题
现代写法的思路是:传参过来的这个值是要赋值给this的,参数不用引用,传参的时候就发生了拷贝构造,构造出现的这个对象的内容是this想要的,所以使用swap进行内容的交换,将this内容给vtmp这个局部变量,并且让vtmp帮忙释放这块旧空间(生命周期结束调用析构函数完成资源清理)如果使用的是memcpy增容后和增容前,这些旧数据指向的是同一块内存空间,但是增容后旧的空间被释放了,所以打印的时候会出现随机值,扩容后的对象声明周期结束的时候,对同一块内存空间释放第二次导致了程序崩溃。原创 2024-03-16 16:49:30 · 881 阅读 · 0 评论 -
STL_vector详解和迭代器失效问题解释
vector是一个大小动态可变的一个数组的序列容器。动态可变自然就是他的大小可以根据插入的数据多少动态的扩容,来适应存储更多的数据。内存不够了会自动增容。数组也就是说vector可以像数组一样使用下标对每个元素进行高效的访问与修改。并且他也像数组一样在内存之中占用一块连续的内存空间。容器就是说明这个vector可以存储各种类型的数据也可以是其他容器。第一个参数是模板参数,指明了vector可以存储任意类型的数据,第二个参数alloc是空间配置器,也就是内存池。原创 2024-03-16 16:47:44 · 784 阅读 · 0 评论 -
类和对象(上)--关于面向对象,类的定义,访问限定符,this指针
关于类的定义这里因为C++是兼容C语言的,所以C++给C语言的struct一个新的定义,就是用来定义类,C语言中关于结构体的用法C++这里同样也是兼容的。;;int* _a;int _top;定义一个类实际就是一个类型(花括号括起来的就是一个作用域,类的作用域就叫类域),类里面可以定义成员变量_top等,也可以定义成员函数就是Init和Push。name就是类名,成员变量和成员函数组成了类体。struct毕竟是C语言的产物,C++还有一个关键字class来定义类class stu。原创 2024-03-16 11:34:53 · 1035 阅读 · 0 评论 -
string类代码详解和写时拷贝
二次修订于date:2024:3:16string类的模拟实现可以加深对于string类的理解。一般实现简单的string类就是string的默认成员函数中的四个,构造函数,拷贝构造,赋值运算符重载,析构函数。原创 2024-03-16 11:32:19 · 839 阅读 · 0 评论 -
STL string的使用介绍
注意这里size的改变,在windows下缩小的时候capacity是没有跟着变化的,但是在别的编译器就不一定了,因为不同的版本的stl都是按照c++标准来实现的,功能是一样的,但是底层的一些细节是不同的,比如增容的时候是标准扩容二倍还是根据情况。解释一下文档:resize就是将这个字符串调整为n个字符的长度,如果原来的长度大于n,大于n的那一部分就会被移除,也就是将size变为n,如果原来的字符串长度小于n,那么会在原来字符串后面追加字符c使得size达到n,如果没有给c传参,那么c默认是空字符。原创 2024-03-14 19:41:07 · 355 阅读 · 0 评论 -
C++11新特性解析
C++11就是C++在继C++98之后推出的第一个添加了重大改进的版本,相比于C++98增加了很多有用的特性,但是C++11从出来开始也饱受诟病,因为C++11不仅增加了很多有用的特性也增加了很多无用的特性,这就无型之中增大了C++语言的学习难度。相比于C++98/03,C++11则带来了数量可观的变化,其中包含了约140个新特性,以及对C++03标准中约600个缺陷的修正,这使得C++11更像是从C++98/03中孕育出的一种新语言。相比较而言,原创 2022-10-15 21:35:03 · 748 阅读 · 0 评论 -
C++STL哈希表
哈希算法是如何不通过比较就能确定一个数据在不在呢?答案是:通过将数据插入的位置与关键字建立映射关系,这种映射关系就是后面要说到的哈希函数简单举个例子:现在有这样一个场景,给你了一个长度为N的字符串,需要你在O(N)的时间复杂度内找出所有只出现过一次的字符。这时候我们就可使用哈希算法中的直接定址法来解决。什么是直接定址法呢?就是我们创建一个长度为128的计数数组,然后用字符的ascii码值直接映射到数组的这个位置,对这个位置进行++。原创 2022-10-08 09:18:22 · 1453 阅读 · 0 评论 -
C++——多态
多态是什么,直接看就是多种形态。具体细讲就是不同对象在完成同一种行为的时候结果不同。很常见的一种情况就是不同的对象,调用同一个函数,但是出现了不同的结果.1.静态多态:函数重载(看起来调用的是一个函数但是传递不同的参数有不同的行为,cout的自动识别)2.动态多态:一个父类对象的引用或者指针去调用一个函数,传递不同的对象会出现不同的行为静态:是指在编译阶段实现动态:是指在程序运行阶段实现被virtual修饰的函数就是虚函数public :} };这里的func1就是虚函数。原创 2022-09-15 12:36:56 · 786 阅读 · 2 评论 -
C++——面向对象三大特性之继承
继承的核心是代码的复用,继承机制就是面向对象语言对于类保持原来的结构,并对其进行扩展的重要手段。在继承里面有这样两个类,基类(父类),派生类(子类),根据名称可以看出他们之间的关系。继承就是子类继承父类,子类的结构相当于是在父类的结构上面的一个扩展。继承是类在设计层次的复用。继承可以说是C++语法复杂的一个方面,因为有了多继承,所以就会存在菱形继承,为了解决菱形继承又有了菱形虚拟继承。不仅底层实现复杂,对性能也有影响。所以一般不能设计出菱形继承。大多数情况都是使用单继承。像是java只有单继承。原创 2022-09-08 19:20:58 · 553 阅读 · 0 评论 -
queue和priority_queue使用+模拟实现
deque与vector比较,头部的插入和删除不需要移动数据效率更高扩容的时候因为map数组里面存放的是指针,所以在扩容的时候的拷贝会比vector拷贝全部数据的效率高很多。与list相比,存储空间是连续的,空间利用率高,同时缓存命中率高,因为连续的数据空间,每次缓存加载的时候都是加载一块空间而不是单个数据空间。但是,原创 2022-09-03 04:00:00 · 300 阅读 · 0 评论 -
stack使用+模拟实现
思路:使用优先级队列,优先级队列实际就是将vector封装然后加上堆的算法,实际就是一个堆,用nums构建一个优先级队列,默认是大堆,但是这里需要小堆,用前k个数字构建一个小堆,然后遍历剩下的数字,如果遇到比堆顶元素大的那么就删除堆顶元素然后插入新元素,最后这个堆里面的k个数就是整个nums里面最大的k个,第k大的数字就是这个堆里面最小的数字。3.如果该运算符的优先级低于栈顶的运算符,那么出栈顶的运算符,该运算符继续和栈顶的运算符比较,直到该运算符优先级大于栈顶元素,或者栈为空,就将该运算符入栈。原创 2022-09-01 20:40:10 · 232 阅读 · 0 评论 -
STL——list使用和模拟
在STL中list底层使用的是双向带头循环链表,这是一个很完善的结构,可以做到在O(1)时间内完成任意位置的插入和删除。唯一的缺点就是不支持随机访问,如果要访问list中的第三个元素,只能通过遍历比如迭代器或者范围for来遍历到第三个元素。所以list不支持算法库里面的sort(因为算法库中的sort底层是快速排序,快速排序为了防止最坏的情况也就是已排序好的数据,在这种情况下的效率就是O(N^2)因此引入了三数取中,但是如果不支持随机访问,三数取中就不可以使用了)...原创 2022-08-31 11:40:02 · 228 阅读 · 0 评论 -
vector模拟(C++)和注意问题
现代写法的思路就是传参过来的这个值是要赋值给this的,参数不用引用,传参的时候就发生了拷贝构造,构造出现的这个对象的内容正式this想要的,所以使用自己实现的swap进行内容的交换,将旧的内容给v这个局部变量,并且让v帮忙释放这块空间(生命周期结束调用析构函数完成资源清理)这里可以看到如果使用的是memcpy增容后和增容前,这些旧数据指向的是同一块内存空间,但是增容后旧的空间被释放了,所以打印的时候会出现随机值,最后扩容后的对象声明周期结束的时候,对同一块内存空间释放了两次导致了程序崩溃。...原创 2022-07-29 11:32:02 · 124 阅读 · 0 评论 -
vector详解和迭代器失效问题
下面来看一下这个使用迭代器来给vector初始化。答案是:不可以vector空间函数的使用vector的增删查改vector增删查改函数作用简介push_back尾插pop_back尾删find在容器内查找(这并不是vector的成员函数,是算法模块实现的)insert在pos位置之前插入一个valerase删除pos位置的值,或者删除迭代器区间swap交换两个vector的数据空间operator[ ]类似数组访原创 2022-07-25 18:18:41 · 652 阅读 · 0 评论 -
string类的模拟实现(C++)
string的模拟实现原创 2022-07-24 08:22:34 · 209 阅读 · 0 评论 -
C++编译器优化问题
首先使用a拷贝构造了形参aa,然后aa拷贝构造了copy1,copy1拷贝构造了copy2(注意这里虽然是等号也是拷贝构造,因为这里的copy2还是对象创建初始化阶段,只有对象创建出来之后再给对象赋值才是赋值)copy2拷贝构造了一个临时对象然后传参给test,使用这个临时对象1拷贝构造了aa然后aa重复上面再函数中的拷贝构造,返回值,因为是值返回所以先再main函数的栈帧内开辟一个临时对象2,调用了一次拷贝构造,然后再用哦这个临时对象2,拷贝构造了ret对象。所以编译器进行了优化,那么优化的地方在哪呢?.原创 2022-07-18 01:30:00 · 1088 阅读 · 0 评论 -
C++模板(函数模板和类模板)
C语言中如果要实现两个数交换,可以实现一个函数,但是如果是不同类型的数值,比如int和double却是不能使用同一个函数。如下代码:这段代码显然只能实现int类型的交换而c,d的交换只能再写一个函数。这里编译器可以根据我们传过去的参数类型去推导T的类型,然后将模板实例化,就是按照我们写的函数模板实例化出来一个具体类型的函数如int或者double思考一个问题:既然编译器根据传参实例化的函数,那如果传参的两个参数不同呢?但是如果要实现一个参数两种类型,有如下方法,比如实现的是Add函数(因为交换两个原创 2022-06-23 20:03:07 · 494 阅读 · 0 评论 -
C++内存管理(new/delete)
如图:从上到下依次时栈,堆,数据段,代码段。栈一般是用来存放局部变量,返回值,维护函数栈帧等内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。堆就是负责动态内存开辟,也就是今天要使用的new开辟内存的地方。数据段存放的是静态变量,全局数据,全局数据又会分为已初始化全局数据区和未初始化全局数据区。代码段中存放的就是可以执行的代码(一般是在汇编阶段完成后存放的二进制机器指令,同时常量也是存放在这块区间)。图中可以看到栈是向下增长的,堆原创 2022-06-22 22:19:39 · 241 阅读 · 0 评论 -
类和对象(下)[初始化列表、explicit关键字、static成员、C++11缺省值初始化、友元、内部类]
上面这种就是函数体内初始化。但是其实上面这个并不能称之为初始化,因为初始化只能进行一次,就是在创建这个对象的时候,上面准确的说是在给创建好的对象赋值,因为赋值可以多次赋值,在这个函数体内就可以多次赋值。首先这两种初始化方式是可以混用的,比如像下面这样子初始化列表的特性1,每个变量在初始化只能初始化一次,因此类中的每个变量只能在初始化列表中出现一次。2,以下成员必须放在初始化列表中进行初始化:引用类型的成员变量,const类型的成员变量,自定义类型成员(没有默认构造函数)3,尽量使用初始化列原创 2022-06-21 22:19:40 · 341 阅读 · 0 评论 -
类和对象 (中)[类的6个默认成员函数]
这六个是类的默认成员函数我们以前在写C语言的数据结构的时候,经常会忘记调用Init初始化数据结构,这里的构造函数就是为了解决对象没有初始化的问题,因为构造函数会在对象实例化的时候自动调用进行初始化。下面来看代码这里可以看到我们写了一个Date()的构造函数,创建对象后并不需要我们主动调用这个对象就已经初始化好了。注意:void并不是无返回值而是空返回值,这里无返回值我们就直接不写。当然如果我们想要主动传参也是可以的。就如下面这样:这里要注意写法,是直接将参数跟在对象后面,这样就可以给构造函数传参了,原创 2022-06-19 19:42:04 · 61 阅读 · 0 评论 -
类和对象 [类的定义、作用域、实例化、以及对象大小计算、this指针]
关于类的定义这里因为C++是兼容C语言的,所以C++给C语言的struct一个新的定义,就是用来定义类,当然C语言中关于结构体的用法c++这里同样也是兼容的。![image.png](https://img-blog.csdnimg.cn/img_convert/51ef8ab69fd5cffe3dc9c67257fc5b91.png#clientId=u2c41496f-8501-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=607&id=ua7971原创 2022-06-17 21:02:35 · 232 阅读 · 0 评论 -
C++的入门文档(命名空间、输入输出、缺省函数、函数重载、引用、内联函数、auto、范围for、空指针)
C++的输入输出先来看一段程序标准库使用的三种方式缺省函数函数重载这里引出一个问题,为什么c支持函数重载,C语言不支持呢?那c底层又是如何支持函数重载的?引用引用的概念引用和指针的区别引用的使用场景1.做参数引用可以作为参数带回返回值,代替原来的指针的作用,可以让函数带回来两个返回值甚至更多,代码如下2.做返回值某个函数的返回值可以是一个引用,但是前提是返回的这个引用的实体,出了函数的作用域不会被原创 2022-06-17 00:17:46 · 253 阅读 · 0 评论