C++入门基础
XHumble
这个作者很懒,什么都没留下…
展开
-
C++智能指针的解析
为什么需要智能指针是因为我们在没有使用智能指针之前都是使用原生态的指针来管理资源,程序在退出时,原生态的指针不会自动的去释放资源,而c++中还没有支持垃圾回收机制,资源需要用户自己手动进行释放,这就可能由于用户的操作导致内存泄漏,因此用户在写代码时必须要谨慎。什么是内存泄露,内存泄露的危害什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不 是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而 造成.原创 2020-07-29 16:49:48 · 127 阅读 · 0 评论 -
TCP避免丢包机制(滑动窗口机制)
滑动窗口机制的作用:滑动窗口机制实现了流量控制(接收方控制发送方的发送速度),如果发送方发送大量的数据可能会占满接收缓冲区,这样就会导致后续发送的数据无法存放在缓冲区中而丢弃,导致发送方产生了大量的丢包重传。通过流量控制可以避免发送方发送数据过多而导致的丢包重传滑动窗口机制如何实现16为窗口大小是实现滑动窗口机制的关键信息接收方接收到每条数据之后,会进行确认回复,在确认回复的窗口中接收方会填入一个值,这个值不能大于接收方剩余缓冲区的大小,发送方在收到这个回复后,通过窗口大小就知道自己最多原创 2020-07-27 14:07:44 · 1023 阅读 · 0 评论 -
C语言处理错误的传统方式
传统的错误处理机制:1.终止程序: assert 发生内存错误,除0错误时就会终止程序2.返回错误码,缺陷:需要程序员自己去查找对应的错误,如系统都很多库接口函数都是通过把错误码放在errno中表示错误3.C标准库中的setmp和longjmp组合实际中C语言基本都是使用返回错误码的方式处理错误,部分情况下使用终止程序处理非常严重的错误。....原创 2020-07-21 15:21:55 · 179 阅读 · 0 评论 -
C++11 lambda表达式
lambda表达式是为了解决人们在编程时为了实现一个algorithm算法而重新写一个类的情况int main(){ int array[] = {4,1,8,5,3,7,0,9,2,6}; // 默认按照小于比较,排出来结果是升序 std::sort(array, array+sizeof(array)/sizeof(array[0])); // 如果需要降序,需要改变元素的比较规则 std::sort(array, array + sizeof(array) / sizeo原创 2020-07-21 14:22:42 · 138 阅读 · 0 评论 -
C++11右值引用的用法
什么是右值引用C++98提出引用,引用就是起别名,引用变量和被引用实体公用一块内存空间,C++11新提出了右值引用这一概念,右值引用也是起别名,只是它只能对右值引用区别引用和右值引用引用的表现形式:T& REF = 实体; T&& REF = 右值;什么是右值左值与右值是C语言中的概念,但C标准并没有给出严格的区分方式,一般认为:可以放在=左边的,或者能 够取地址的称为左值,只能放在=右边的,或者不能取地址的称为右值,但是也不一定完全正确。 ...原创 2020-07-21 09:54:37 · 235 阅读 · 0 评论 -
undordered系列关联式容器
unordered系列容器的介绍: unordered系列容器是C++11中,新增加的4个关联式容器,这四个关联式容器与红黑树结构的关联式容器使用方式基本相同,只是在底层实现的结构不同。unordered_map1.unordered_map是存储<key , value>键值对的关联式容器,其允许通过key快速的索引到对应的value。2.在unordered_map中,键值通常用于唯一的标记元素,而映射值是一个对象,其内容与键值关联,键值和映射值的类型可能不同。3.在内.原创 2020-07-16 15:22:52 · 343 阅读 · 0 评论 -
红黑树的插入图解
红黑树也属于二叉搜索树,所有它的插入可分为两个步骤步骤1.按照二叉搜索树的规则找到插入新节的位置,并插入新的节点。步骤2.在插入新的节点后,可能会破坏红黑树的性质,所以要对树进行调整。插入 插入的新节点树红色的,若它的双亲节点的颜色是黑色的,则没有破坏红黑树的性质,无需调整,若它的双亲节点的颜色是红色的,则违反了红黑树红色节点不能连在一起的性质,则需要调整:颜色转变 + 旋转情况1:...原创 2020-07-16 15:17:46 · 351 阅读 · 0 评论 -
哈希结构总结
哈希概念:在以往的查找元素的方法是,通常都是与关键码进行比较而进行查找,这是因为元素关键码与它的存储位置之间没有关系,而哈希方式查找元素是可以不通过任何比较,一次直接从表中得到要查找的元素,因为它的存储结构,是通过哈希函数使元素的存储位置而它的关键码之间建立了映射关系,在查找时可以直接通过函数找到该元素插入:1.先通过hash(key) = key % capacity 计算元素在表格中的存储位置2.让元素key插入到表格的pos位置中查找:1.通过hash(key) =..原创 2020-07-13 14:30:01 · 441 阅读 · 0 评论 -
红黑树的结构
红黑树的结构:为了后续实现关联式容器简单,所以为红黑树中增加了一个头节点,头节点也是黑色,它的parent指针域指向红黑树的根节点,left指针域指向红黑树的最小节点(最左侧节点),right指针域指向红黑树中的最大节点(最右侧节点)...原创 2020-07-08 16:04:06 · 237 阅读 · 0 评论 -
红黑树中节点的默认颜色为什么是红色
关于节点默认是红色还是黑色,可以通过给树中插入红色节点或者黑色节点对树造成的影响大小,而判断应该将节点的默认颜色设置为红色还是黑色。根据红黑树的性质:1. 每个结点不是红色就是黑色 2. 根节点是黑色的3. 如果一个节点是红色的,则它的两个孩子结点是黑色的4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数目的黑色结点5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点) 插入红色节点树的性质可能不会改变,而插入黑色节点每次都会违反性质...原创 2020-07-08 15:29:53 · 4367 阅读 · 0 评论 -
红黑树的知识点总结(概念 、 性质)
红黑树的概念 红黑树是二叉搜索树的一种,它在二叉搜索树的基础上给每个结点增加颜色,可以是红色或者是黑色,所以叫做红黑树。通过对对节点颜色的限制,红黑树确保了没有一条路径会比其他路径长出两倍,而达到接近平衡。红黑树的性质每个节点只能是红色或者黑色 根节点必须是黑色的 如果一个结点是红色的,则它的两个孩子结点都要是黑色的 对于每个结点,从该节点到其所有后代叶结点的简单路径上,黑色节点的个数都相等 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)总结:红黑树:二叉搜索数 + 给结点.原创 2020-07-08 14:59:56 · 884 阅读 · 0 评论 -
AVL树的插入
AVL树就是在二叉搜索树的基础上添加了平衡因子,为了平衡因子符合不超过(-1 / 1 / 1)的条件,所以有时候在插入的时候要对树进行调整。它的插入就是在二叉搜索树插入的基础上进行对树进行调整,使之符合AVL树的性质ALV树节点的定义:template<class T>class AVLTreeNode{ typedef AVLTreeNode Node;public: AVLTreeNode(const T& data) :_pLeft(nullptr) ,原创 2020-07-06 09:55:33 · 149 阅读 · 0 评论 -
AVL树的基本概念(概念、性质)
目录AVL树的概念AVL树的性质:AVL树是如何实现的AVL树的概念二叉搜索树在数据接近有序的时候,可能会退化为单支树,这时候它就不具备查找效率高效的优点了,单支树就相当于在顺序表中查找时间复杂度为O(N),当二叉搜索树接近为完全二叉树时这时它的查找效率是最高的时间复杂度为O(log2N)。AVL树就是为了避免树退化为单支树而创建的树,规定在向二叉搜索树中插入新节点时,如果能保证每个节点的左右子树高度之差的绝对值不超1(需要对树中的节点进行调整),即可降低树的高度,从而减少平均.原创 2020-07-06 09:02:46 · 1513 阅读 · 0 评论 -
二叉搜索树中查找节点的时间复杂度
在二叉搜索树的插入和删除操作都必须先查找,查找的效率代表了二叉搜索树中各个操作的性能这种情况是最优的情况下,并不代表二叉搜索树的时间复杂度在构建二叉搜索树时,如果插入元素有序或接近有序,如 1 2 3 4 5 6,二叉搜索树退化成为一颗单支树,此时查找的时间复杂度为O(N)所以为了提高二叉搜索树操作的效率,在构建二叉搜索树时尽量避免出现单支树的情况出现通过一些机制是可以避免在构建二叉树时出现单支树的情况------平衡二叉搜索树AVL树 和 红黑树...原创 2020-07-02 14:48:39 · 12823 阅读 · 0 评论 -
二叉搜索树的操作(重点了解删除操作)
二叉搜素树的查找: 若是空树,直接返回false 若不是空树,则分为以下几种情况 1.如果根节点data = 查找的data, 返回true 2.如果根节点data > 查找的data,在其左子树查找 3.如果根节点data < 查找的data, 在其右子树查找PNode find(const T& data) { if(nullptr == _pRoot) return nullptr; PNode pcur = _...原创 2020-07-02 14:23:41 · 362 阅读 · 0 评论 -
二叉搜索树的概念
二叉搜索树的概念:二叉搜索树又称而二叉排序树,它或者是一颗空树,或者是具有以下性质的二叉树1.若它的左子树不为空,则左子树上所有节点的值都小于根节点的值2.若它的右子树不为空,则右子树上所有节点的值都大于根节点的值3.它的左右子树也分别为二叉搜索树...原创 2020-07-02 10:28:34 · 659 阅读 · 0 评论 -
C++ map和set
序列式容器与关联式容器C++容器分为序列式容器和关联式容器,序列式容器比如:vector list deque 等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构(顺序表),里面存储的是元素本身,这一点和关联式容器不同,关联式容器存储的是<key , value>结构的键值对,对数据的检索时比序列式容器效率更高。什么是键值对键值对是用来表示一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值value表示与key对应的信息SGI-ST原创 2020-07-01 16:10:29 · 202 阅读 · 0 评论 -
多态的原理
1.如果类中包含虚函数,用户没有显式给出构造函数编译器会给该类生成一份默认的构造函数。2.如果类中包含虚函数,类对象模型会都出4个字节3.对象前4个字节中的内容是在构造函数中编译器填充的4.对象的前4个字节中内容,实际上是一个指针5.对象前4个字节的指针指向了块内存空间,内存空间存放的是虚函数的入口地址class Base{public: virtual void Func1() { cout << "Func1()" << endl; }p.原创 2020-07-01 10:42:49 · 136 阅读 · 0 评论 -
编译器自动生成默认构造函数的情况
在用户没有显式的给出类中的默认成员函数时,编译器将会生成一个默认的 --- 如果用户显式的实现了则编译器将不会生成。但是编译器厂商并没有严格的按照语法来实现,并不是用户没有显式的给出则编译器会自动生成一份。什么情况下编译器才会生成?1.A类有默认的构造函数,B类没有定义任何函数,B类中包含A类的对象,编译器将来一定会给B类生成一份无参的构造函数。2.继承体系中,基类显式定义默认构造函数,子类中没有定义任何的构造函数,编译器将来一定会给B类生成一份无参的构造函数。3.虚拟继承中:如果子类没原创 2020-07-01 09:11:42 · 336 阅读 · 0 评论 -
抽象类 接口继承 实现继承
抽象类的概念:在虚函数的后面写上 =0 ,则这个函数为纯虚函数。包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。派生类继承后也不能实例化出对象,只要重写纯虚函数,派生类才能实例化出对象。纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承。class Car{public: virtual void Drive() = 0;};class Benz :public Car{public: virtual void Drive() { cout <原创 2020-07-01 08:52:50 · 236 阅读 · 0 评论 -
重载、重写、重定义的对比
函数重载:1.必须在同一个作用域2.函数名字必须相同3.参数列表必须不同(参数个数、参数类型、参数次序)4.与函数返回值无关重定义:1.必须在继承体系中2.子类和基类具有相同名称的成员,可以是成员函数:只有名字相同,与原型是否相同无关。成员变量:只有名字相同,与成员变量的类型无关3.通过派生类对象调用同名成员时,调用的都是子类的成员,基类的无法直接调用到 ----- 子类同名成员隐藏了基类的同名成员重写:1,必须在继承体系中2.基类中函数必须是虚函数3.派生类原创 2020-06-30 16:10:36 · 163 阅读 · 0 评论 -
override和final
C++对函数重写要求比较严格,但是有些情况下由于函数名的字母的次序问题写反而无法重写,这种错误在编译阶段是不会报出的,只有在程序运行时没有得到预期结果才来dabug会得不偿失,因此C++11提供了override和final两个关键字,可以帮助用户检测是否重写。1.final:修饰虚函数,表示该虚函数不能在被继承class Car{public: virtual void Drive() final {}};class Benz :public Car{public: virtua原创 2020-06-30 15:54:04 · 510 阅读 · 1 评论 -
什么是多态
讲一讲什么是多态:1.多态的概念:同一个事物在不同场景下表现出不同的状态举一个例子进行说明:比如买票这个行为,当普通人买票时,是全价买票;学生买票时,是半价买票;军人买票时是优 先买票。 再举个栗子: 最近为了争夺在线支付市场,支付宝年底经常会做诱人的扫红包-支付-给奖励金的活动。那么 大家想想为什么有人扫的红包又大又新鲜8块、10块...,而有人扫的红包都是1毛,5毛....。其实这背后也是 一个多态行为。支付宝首先会分析你的账户数据,比如你是新用户、比如你没有经常支付..原创 2020-06-30 15:29:37 · 1442 阅读 · 0 评论 -
虚拟继承解决菱形继承二义性的原理
虚拟继承:重点了解编译器为派生类中新增的4个字节:对象的前4个字节存放的是虚基表的地址,虚基表里面存放是的派生类对象相对于自己的偏移量和派生类对象相对于基类部分的偏移量。菱形虚拟继承方式如何解决二义性问题:让最顶层基类中的成员在最底层派生类对象中只存储一份通过虚基表的存放的偏移量来访问最顶层基类中的成员...原创 2020-06-30 14:21:12 · 191 阅读 · 0 评论 -
C++继承 菱形继承
单继承:一个子类只有一个直接父类时称这个继承关系为单继承多继承:一个子类有两个以上直接父类时称这个继承关系为多继承菱形继承:菱形继承是多继承的一种特殊情况菱形继承的问题:菱形继承有数据冗余和二义性问题菱形继承二义性的解决方式:方式一: 在最底层派生类中,实际存储了两份最顶类中的成员,导致访问不明确,在访问时明确告诉编译器访问那个基类通过上述方式,代码虽然可以通过编译,但是没有从本质上解决问题 ---- Chile中仍然存储了两份Person中的内容方式二.原创 2020-06-30 10:35:04 · 187 阅读 · 0 评论 -
C++继承 ——派生类的默认成员函数
在学习类的时候,我们了解到类中有6个默认成员函数,默认函数是我们在没有显式给出这个函数时,编译器会自动生成一个,那么在派生类中是否会自动生成时如何生成? 1.派生类的构造函数必须调用基类的构造函数用来初始化基类的那一部分,如果基类没有默认构造函数,则必须在派生构造函数的初始化列表阶段显式调用。 2.派生类的拷贝构造函数必须调用基类的拷贝构造函数完成基类的拷贝初始化。 3. 派生类的operator=必须要调用积累的operator=完成基类的复制。 4.派生类的析构函数会在调用完成后...原创 2020-06-30 10:07:34 · 191 阅读 · 0 评论 -
STL—vector类
vector的介绍:1.vector是表示可变大小的数组序列容器。2.vector采用连续存储空间来存储元素,就像数组一样,可以采用下标对vercot的元素进行访问,vertor的底层采用动态的顺序表,它的大小是可以改变的,而且它的大小会被容器自动处理。vector的使用1.vector的定义: vector<int> v1(); // 无参构造 vector<int> v2(10,5); // 构造并初始化10个5 int array[]原创 2020-06-28 14:48:11 · 182 阅读 · 0 评论 -
C++继承——继承中的作用域
继承中的作用域1、在继承体系中基类和派生类都有独立的作用域。2、派生类和基类中有同名成员,派生类成员将屏蔽基类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。在派生类成员函数中,可以通过使用 基类::基类成员 显示访问3、注意如果是成员函数名相同就构成了隐藏。// Student的_num和Person的_num构成隐藏关系,可以看出这样代码虽然能跑,但是非常容易混淆class Person{protected : string _name = "小李子"; // 姓名 in.原创 2020-06-20 15:52:55 · 586 阅读 · 0 评论 -
C++继承 ——基类和派生类对象赋值转换
基类和派生类对象赋值转换:派生类对象 可以赋值为 基类的对象 / 基类的指针 / 基类的引用。基类对象不能赋值给派生类对象。基类的指针可以通过强制类型转换赋值给派生类的指针,但是必须是基类的指针是指向派生类对象时才是安全的。#include <iostream>using namespace std;#include <string>class Person{protected : string _name; // 姓名 string _sex; .原创 2020-06-20 15:39:31 · 1800 阅读 · 0 评论 -
C++中继承 —— 继承的概念及定义
继承的概念及定义: 继承是面向对象程序设计使代码可以复用的最重要的手段,允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生的新类,称为派生类。继承呈现了面向对象程序设计的层次结构,体现了有简单到复杂的认知过程,以前我们接触的复用都是函数复用,继承使类设计层次的复用。#include <iostream>using namespace std;#include <string>// 人class Person{public: void Set.原创 2020-06-20 15:31:12 · 1561 阅读 · 0 评论 -
string类中的浅拷贝与深拷贝问题
在模拟实现string类时,需要注意拷贝构造函数与operator=函数,不能将这个对象里的指针的值赋值给另一个对象里的指针,两个指针指向了同一个空间,这就是浅拷贝,在不涉及资源的管理时浅拷贝是可以的,若涉及资源管理就会造成同一块空间被多次释放而导致代码崩溃。当s1被销毁时这块空间就会被释放,s2销毁时这块空间又要被释放,这明显是不合理的,会导致代码的崩溃。解决办法:深拷贝深拷贝就是让每个对象都有一份资源,而不会多个对象同时指向同一块空间。传统写法:首先给_str分配原创 2020-05-31 23:13:39 · 808 阅读 · 0 评论 -
C++ string类
string : 管理字符串,字符的容器,专门存放字符的动态顺序表string类中变量 :size capacity 字符string类中为了提高性能,才类中提供了一个长度为16个字符大小的数组,因为存放 \0 所以capacity是15string类对象的容量操作size 返回字符串有效字符长度length 返回字符串有效字符长度capacity 返回空间总大小empty 检测字符串释放为空串,是返回true,否则返回falseclear 清空有效字符res...原创 2020-05-13 16:19:42 · 339 阅读 · 0 评论 -
C++ 函数模板
函数模板是什么?函数模板不是一个真正的函数,只是编译器生成代码的模具,程序员给编译器生成代码的一种规则template 操作符使用:template<typename T> //模板参数T Add(T left, T right) // 参数列表函数模板可以实现一个通用类型的函数,上面就是一个通用类型的加法函数注意:1. 如果模板参数列表中有多个类型的参数,每个参数前都必须要添加typename2. 在模板参数列表中既可以使用type...原创 2020-05-11 23:11:09 · 213 阅读 · 0 评论 -
new/delete的原理(脑图)
new的原理 :delete的原理:原创 2020-05-11 22:39:58 · 105 阅读 · 0 评论 -
static关键字
目录C语言中的static:修饰变量:修饰全局变量:修饰函数:C++中的static修饰类的成员变量静态成员函数C语言中的static:修饰变量: 修饰局部变量: 延长了局部变量的生命周期,不会随着函数的结束而结束,记忆动能:下次使用可以时可以看到上一次的结果注意:普通的局部变量存储于栈空间中,使用完会被销毁,静态局部变量使用static修饰符定...原创 2020-05-07 17:21:35 · 122 阅读 · 0 评论 -
C++ 赋值运算符重载
运算符重载C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类 型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。运算符重载可以让编译器按照指定的规则对自定义类型对象直接进行一些运算符操作。函数名字为:关键字operator后面接需要重载的运算符符号。函数原型:返回值类型 operator操作符(参数列表)class D...原创 2020-04-29 10:50:29 · 376 阅读 · 0 评论 -
C++ 拷贝构造函数
拷贝构造函数的概念 在创建对象时,可否创建一个与一个对象一某一样的新对象呢,通过拷贝构造函数就可以实现 拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象 创建新对象时由编译器自动调用。拷贝构造函数的实现:class Date{public: Date(int year = 2020,int month = 1,...原创 2020-04-28 13:44:15 · 128 阅读 · 0 评论 -
C++ 析构函数
析构函数的概念于构造函数功能相反,析构函数不是完成对象的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成类的一些资源清理工作析构函数的作用 清理对象中的资源(从堆上申请的资源,打开的文件)析构函数的使用在对象的生命周期结束时,C++编译器会自动调用析构函数,若用户没有显式定义析构函数,则编译器会自动生成默认析构函数,一般情况下在类中不涉及资源的管...原创 2020-04-28 09:56:52 · 358 阅读 · 0 评论 -
C++ 构造函数与默认构造函数
什么是构造函数:构造函数是一个特殊的成员函数,构造函数没有返回值而且函数名与类名相同,创建类类型对象时由编译器自动调用,保证每个数据成员 都有 一个合适的初始值,并且在对象的生命周期内只调用一次。为什么使用构造函数 我们在创建一个对象后,通常需要给对象设置信息,我们可以用调用方法来给对象设置信息,但是如果每次创建对象都调用该方法设置信 息,未免有点麻烦,构造函数可以在对象创建时...原创 2020-04-25 18:29:07 · 508 阅读 · 0 评论 -
C++ this指针
什么是this指针C++编译器给类中的每个成员函数都设置了一个隐藏的参数this指针,该指针指向调用该成员函数的对象,在成员函数中访问的每个成员变量,实际上访问的是this指向的对象。在C语言中在对s1进行初始化时需要将s1的地址传递,这样编译器才知道是给s1进行初始化,而在C++中分明有两个对象,StudentInit函数中没有区分对象的参数,那为什么当s1调用Sutdent函数时,...原创 2020-04-25 15:40:29 · 346 阅读 · 0 评论