
03 深入理解 c++
文章平均质量分 87
c++
且听吟风°
扣:903199567
展开
-
01 前言
C语言是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的程序,需要高度的抽象和建模时,C语言则不合适。为了解决软件危机, 20世纪80年代, 计算机界提出了OOP(object oriented programming:面向对象)思想,支持面向对象的程序设计语言应运而生。1982年,Bjarne Stroustrup博士在C语言的基础上引入并扩充了面向对象的概念,发明了一种新的程序语言。为了表达该语言与C语言的渊源关系,命名为C++。原创 2024-02-14 14:42:06 · 889 阅读 · 0 评论 -
02 c++入门
定义命名空间,需要使用namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中为命名空间的成员1.正常的命名空间定义//命名空间可以定义变量/函数/类型int val;//2.命名空间可以嵌套int a;int b;int c;int d;//3.同一个工程中允许多个相同名称的命名空间,最后会合并成一个命名空间注意: 一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中。原创 2024-02-16 20:52:48 · 746 阅读 · 0 评论 -
03 类和对象 1
c语言是面向过程的,关注的是过程,分析求解问题的步骤,通过函数调用逐步解决问题如洗衣服的过程,面向过程会按照步骤一步步来面向对象关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成洗衣服总共有4个对象,人、衣服、洗衣粉、洗衣机过程:人将衣服放入,倒入洗衣粉,启动洗衣机,完成甩干整个过程主要是这4个对象之间交互完成,不需要关注具体如何洗衣服c语言结构体中只能定义变量,c++中不仅可以定义变量,也可以定义函数,之前的栈以c++的方式定义在c++中,结构体struct关键字用class代替c原创 2024-02-18 11:46:39 · 828 阅读 · 0 评论 -
04 类和对象 2
无参构造函数,全缺省构造函数,编译器自动生成的构造函数,都可以认为是默认构造函数。析构函数:与构造函数功能相反,析构函数不是完成对象本身的销毁,局部对象销毁工作由编译器完成,而对象在销毁时会自动调用析构函数,完成对象资源的清理工作。是一个特殊的成员函数,名字与类相同,创建类类型对象时由编译器自动调用,保证每个数据成员由一个合适的初始值,并且在对象整个生命周期只调用一次。构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。原创 2024-02-21 00:24:36 · 841 阅读 · 0 评论 -
05 类和对象 3
1.接收返回值对象,尽量拷贝构造方式接收,不要赋值接收2.函数中返回对象时,尽量返回匿名对象3.尽量使用引用传参。原创 2024-02-22 18:46:53 · 895 阅读 · 0 评论 -
06 内存管理
int main()// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数free(p1);delete p2;// 内置类型是几乎是一样的// Cfree(p3);delete p4;free(p5);return 0;原创 2024-02-22 22:36:05 · 941 阅读 · 0 评论 -
07 STL 简介
c++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构和算法的软件框架。原创 2024-02-23 20:50:56 · 730 阅读 · 0 评论 -
08 string类的使用
c语言中,字符串是以\0结尾的一些字符的集合,为了操作方便,c标准库提供了一些str系列的函数,但是这些库函数与字符串是分离开的,不符合OOP的思想,而且底层空间需要自己管理,稍不留神就越界访问。原创 2024-02-27 10:02:59 · 682 阅读 · 0 评论 -
09 string的实现
实现仿cplus官网的的string类,对部分主要功能实现。原创 2024-03-09 21:35:02 · 722 阅读 · 0 评论 -
10 vector的使用
constructor 构造函数声明接口说明vector() 重点无参构造构造并初始化n个valvector (const vector& x) 重点拷贝构造使用迭代器初始化构造InputIterator是可以单向迭代器.是一个模板,可以传任意类型的迭代器,用string的迭代器也没问题。原创 2024-03-10 17:39:24 · 662 阅读 · 0 评论 -
11 vector的实现
实现仿cplus官网的的string类,对部分主要功能实现。原创 2024-03-12 21:05:54 · 500 阅读 · 0 评论 -
12 list的使用
1.list是可以在常数范围内的任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代2.list的底层是带头双向链表循环结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素3.list和forward_list非常相似,最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效4.与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。原创 2024-03-12 23:39:27 · 949 阅读 · 0 评论 -
13 list的实现
实现仿cplus官网的list类,对部分主要功能实现。原创 2024-03-15 17:25:28 · 537 阅读 · 0 评论 -
14 stack和queue的使用
queue文档1.队列是一种容器适配器,专门用在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素2.队列作为容器适配器实现,容器适配器即忒定容器类封装作为其底层容器类,queue提供一组特定成员函数来访问元素,从队尾入队列,队头出队列3.底层容器可以是标准容器模板之一,也可以是其他专门设计的容器类。empty:检测队列是否为空size:返回队列中有效元素的个数front:返回队头元素的引用back:返回队尾元素的引用push_back:在队尾部入队列。原创 2024-03-15 21:13:38 · 274 阅读 · 0 评论 -
15 stack和queue的实现
栈和队列作为容器适配器,只需要将容器封装模板,传入什么容器用什么容器就好了。原创 2024-03-16 11:00:08 · 448 阅读 · 0 评论 -
16 stack和queue习题
逆波兰表达式是已经排好计算顺序的表达式,遇到计算符就取最近的两个操作数计算,得到的结果加入到里面。用两个下标记录压栈和弹栈顺序表,压栈时压栈下标增加,弹栈时弹栈下标增加,如果栈顶元素和弹栈表相等就弹出,栈为空且弹栈下标等于它的长度,说明全部匹配了。用两个栈实现,一个栈正常插入和删除,另一个栈记录当前最小元素,第一个栈删除的时候,如果和最小的栈顶元素相等,最小的栈也删除元素。2.遇到右括号,将栈内元素不停弹出,直到匹配到左括号,将左右括号丢弃。1.如果这个运算符比栈顶的运算符优先级高,进栈。原创 2024-03-17 00:00:24 · 278 阅读 · 0 评论 -
17 deque
deuqe双端队列:是一种双开口的连续空间的数据结构,可以在头尾两端进行插入和删除,时间复杂度为O(1),不需要移动元素,和list比较,空间利用率比较高。原创 2024-03-18 10:20:53 · 354 阅读 · 0 评论 -
18 优先级队列
1.优先级队列是一种容器适配器,根据弱排序标准,它的第一个元素总是最大的2.此上下文类似于堆,堆中可以随时插入元素,检索最大堆元素3.优先队列实现为容器适配器,容器适配器即将特定容器类封装作为底层容器类,queue提供一组特定的成员函数访问其元素,元素从特定容器的“尾部”弹出,称为优先级队列的顶部。原创 2024-03-18 23:03:26 · 735 阅读 · 0 评论 -
19 反向迭代器
对于链表我们可以重载它的++,因为将指针封装成了类,而vector的迭代器就是原生指针的重命名,当然,也可以封装为类就可以实现反向迭代器,不过过于麻烦。用这样一个反向迭代器的类,可以实现其他所有数据的反向迭代器,只需要传入对应数据类型的正向迭代器就能构造反向迭代器,这是如何实现的。想要第一个输出5,需要反向迭代器rbegin在5的位置,判断输出完的条件,rend在头节点的位置就行,只需要将指针相加重载为取前一个数据,这就需要和正向迭代器一样封装一个反向迭代器的类。先用链表的迭代器做示范。原创 2024-03-21 23:20:06 · 411 阅读 · 0 评论 -
20 模板进阶
一个程序由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将做事有目标文件链接起来形成单一的可执行文件的过程为分离编译模式。原创 2024-03-23 23:39:29 · 818 阅读 · 0 评论 -
21 继承
继承(inheritance)机制是面向对象程序设计使代码可以服用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类.继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程.以前我们接触的复用都是函数复用,继承是类设计层次的复用public:protected:// 姓名// 年龄// 继承后父类的Person的成员(成员函数+成员变量)都会变成子类的一部分。这里体现出了//Student和Teacher复用了Person的成员。原创 2024-03-27 18:29:39 · 744 阅读 · 0 评论 -
22 多态
需要声明的,下面的代码和解释的哦朴实vs2013x86环境,涉及指针是4bytes,如果要其他平台下,部分代码需要改动。比如:如果是x64程序,则需要考虑指针是8bytes问题等等多态是在不同继承关系的类对象,取调用同一函数,产生了不同的行为。比如Student继承了Person,Person买全价,Student就半价必须通过基类的指针或引用调用虚函数被调用的函数必须是虚函数,且派生类必须对基类的虚函数重写。原创 2024-03-29 20:14:37 · 1275 阅读 · 0 评论 -
23 二叉搜索树
1.内容安排说明2.二叉搜索树实现3.应用分析4.进阶题。原创 2024-06-08 11:05:53 · 902 阅读 · 0 评论 -
24 map和set
set文档介绍1.set是按照一定次序存储元素的容器2.在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中元素不能在容器中修改(元素总是const),但可以从容器中插入或删除3.在内部,set中的元素不可以重复(因此可以使用set去重)4.使用set的迭代器遍历set中的元素,可以得到有序序列5.set中的元素默认按照小于来比较log2Nlog2Nlog2N7.元素不允许修改,可能会破坏结构。原创 2024-04-07 16:59:17 · 596 阅读 · 0 评论 -
25 avl树
节点保存左右孩子和模板数据,因为要调整高度,所以保存双亲和平衡因子int _bf;{}假如以pParent为根的子树不平衡,即pParent的平衡因子为2或者-2,分以下情况考虑1.pParent的平衡因子为2,说明pParent的右子树高,设pParent的右子树的根为pSubR当pSubR的平衡因子为1时,执行左单旋当pSubR的平衡因子为-1时,执行右左双旋2.pParent的平衡因子-2,说明pParent的左子树高,设pParent的左子树的根为pSubL。原创 2024-06-17 01:12:27 · 968 阅读 · 0 评论 -
26 红黑树
枚举一个颜色,红和黑,节点中加入颜色enum colorRED,BLACKcolor _col;{}为什么节点默认是红色?因为每条路径的黑色节点数量都必须相等,如果插入结点默认为黑色,就会对所有路径造成影响。如果是红色,最多只会影响自己所在的路径。原创 2024-06-18 22:39:50 · 668 阅读 · 0 评论 -
27 map和set封装
map和set可以采用两套红黑树实现,也可以用同一个红黑树,就需要对前面的结构进行修改迭代器的好处是可以方便遍历,是数据结构的底层实现与用户透明。stl明确规定,begin和edn代表的是一段前闭后开的区间,而对红黑树进行中序遍历后,可以得到一个有序序列,因此:begin可以放在红黑树中最小节点(即最左侧节点)的位置,end放在最大结点(最右侧节点)的下一个位置,关键是最大节点的下一个位置在哪?如果给成nullptr,end的–操作要能找到最后一个元素的位置,最好的方式是将end放在头节点的位置。原创 2024-06-20 01:12:37 · 661 阅读 · 0 评论 -
28 哈希
unordered_map在线文档说明1.unordered_map是存储键值对的关联式容器,其允许通过key快速的索引到与其对应的value2.键值对通常用于唯一的标识元素,而映射值是一个对象,其内容与此键关联。键和映射值的类型可能不同3.在内部,没有对按照任何特定的顺序排序,为了能在常数范围内找到key对应的value,将相同哈希值的键值对放在对应的桶中4.通过key访问单个元素比map快,但它通常在遍历元素子集的范围迭代方面效率较低。原创 2024-06-24 11:12:36 · 917 阅读 · 0 评论 -
29 unordered_set和unordered_map
用哈希结构封装map和set。原创 2024-06-24 16:35:58 · 360 阅读 · 0 评论 -
30 哈希的应用
给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何判断一个数是否在这40亿个整数中1.遍历,时间复杂度O(N)2.二分查找,需要先排序,排序(N*logN),二分查找,logN。1个g大约存储10g字节,40亿个整数就需要160g字节,需要16个g的连续空间,内存中无法开出这么大的容量。3.位图。判断一个数在不在的最小单位可以是位,将整数的范围全部做一个映射,有的值设置为1,没有就设置为0。这样,需要的空间就是42亿个位,0.5个g就可以存下。原创 2024-06-29 22:06:15 · 1074 阅读 · 0 评论 -
31 C++11
在2003年标准委员会提交了一份计数勘误表(简称TC1),使得c++03这个名字已经取代了c++98称为c++11之前的最新的c++标准名称。不过由于c++03(TC1)主要是对c++98标准中的漏洞进行修复,语言的核心部分没有改动,因此人们习惯性的把两个标准合并称为c++98/03标准。从c++0x到c++11,c++标准10年磨一剑,第二个真正意义上的标准姗姗来迟。原创 2024-07-01 21:15:34 · 957 阅读 · 0 评论 -
32 lambda表达式
c++11。原创 2024-07-02 09:46:12 · 1164 阅读 · 0 评论 -
33 包装器
std::bind函数定义在头文件中,是一个函数模板,就像一个函数包装器(适配器),接受一个调用对象(callable object),生成一个新的可调用对象来“适应”原对象的参数列表。arg_list中的参数可能包含形如_n的名字,其中n是一个证书,这些参数是“占位符”,表示newCallable的参数,它们占据了传递给newCallable的参数的“位置”。其中,newCallable本身是一个可调用对象,arg_list是一个逗号分隔的参数列表,对应给定的callable的参数。原创 2024-07-02 13:54:10 · 420 阅读 · 0 评论 -
34 异常
很多时候会自定义异常体系管理,如果一个项目随便抛异常,那么外层的调用者就没法处理,所以有一套规范,排出的都是继承的派生类对象,捕获一个基类就好了// 服务器开发中通常使用的异常继承体系public:, _id(id){}protected:int _id;return str;原创 2024-07-03 00:56:06 · 565 阅读 · 0 评论 -
35 智能指针
内存泄露指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况,并不是指内存在物理上消失,而是应用程序分配某段内存后,因为设计错误,失去了对这段内存的控制,因而造成了内存的浪费危害:长期运行的程序出现内存泄露,影响很大,如操作系统、后台服务等等,出现内存泄露导致响应越来越慢,最终卡死// 1.内存申请了忘记释放// 2.异常安全问题Func();// 这里Func函数抛异常导致 delete[] p3未执行,p3没被释放.原创 2024-07-04 11:06:59 · 1038 阅读 · 0 评论 -
36 特殊类设计
拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝。原因:1.设置为私有:如果只声明没有设置成private,用户自己如果在类外定义了,就不能禁止拷贝了2.只声明不定义:不定义是y8inwei该函数根本不会调用,定义了也没有意义,不写反而更简单,如果定义了就不会防止成员函数内部拷贝了。原创 2024-07-05 17:26:33 · 363 阅读 · 0 评论 -
37 类型转换
每次使用强制类型转换前,应该自习考虑是否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会。用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用这个,但它不能用于两个不相关的类型转换。因此c++提出了自己的类型转化风格,注意因为c++要兼容c语言,所以c++中还可以使用c语言的转化风格。缺陷:转换的可视性比较差,所有的转换形式都是以一种相同形式书写,难以追踪错误的转换。将父类指针/引用转换为子类对象的指针或引用(动态转换)原创 2024-07-05 23:01:58 · 553 阅读 · 0 评论 -
38 IO流
c语言中,想要将一个整形变量的数据转化为字符串格式,怎么做1.使用itoa()函数2.使用sprintf函数但是两个函数在转化时,需要先给出保存结果的空间,空间给多大,不好界定,而且转化格式不匹配时,可能会得到错误的结果甚至程序崩溃//c++如果是sql2+=的对象是自定义结构体,不支持这个操作。想把结构体转为字符串可以对每个成员单独转,有些麻烦c++可以使用stringstream避开此问题。必须要包含头文件。原创 2024-07-06 20:36:03 · 1061 阅读 · 0 评论 -
39 线程库
在c++11之前,涉及到多线程问题,都是和平台相关的,如windows和linux下各有自己的接口,这使得代码的可移植性差。c++11中最重要的特性就是对线程支持,使得c++在并行编程时不需要依赖第三方库,而且在原子操作中还引入了原子类的概念。要使用标准库的线程,必须包含头文件。C++11线程类函数名功能thread()构造一个线程对象,没有关联任何线程函数,即没有启动任何线程构造一个线程对象,并关联线程函数fn,args1,args2,…为线程函数的参数get_id获取线程id。原创 2024-07-09 17:39:44 · 990 阅读 · 0 评论 -
40 空间配置器(补充)
空间配置器,顾名思义就是为各个容器高效的管理空间(空间的申请与回收的),在默默的工作。虽然在常规使用STL时,可能用不到它,但原理可以了解一下有很大的帮助。原创 2024-07-10 10:14:53 · 920 阅读 · 0 评论