Cpp类和对象(中续)(5)

文章目录

  • 前言
  • 一、赋值运算符重载
    • 运算符重载
    • 赋值运算符重载
    • 赋值运算符不可重载为全局函数
    • 前置++和后置++的重载
  • 二、const修饰成员函数
  • 三、取地址及const取地址操作符重载
  • 四、日期类的实现
    • 构造函数
    • 日期 += 天数
    • 日期 + 天数
    • 日期 -= 天数
    • 日期 - 天数
    • 日期类的大小比较
      • 日期类 > 日期类
      • 日期类 == 日期类
      • 日期类 >= 日期类
      • 日期类 < 日期类
      • 日期类 <= 日期类
      • 日期类 != 日期类
    • 日期类 - 日期类
  • 五、流插入流提取运算符重载
  • 总结


前言

  继承上节的内容,本节内容依旧量大管饱!!


一、赋值运算符重载

运算符重载

  C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,其目的就是让自定义类型可以像内置类型一样可以直接使用运算符进行操作

请记住这个目的!我们的接下来的一切都是围绕这个来展开

  运算符重载函数也具有自己的返回值类型,函数名字以及参数列表。其返回值类型和参数列表与普通函数类似。

  运算符重载函数名为:关键字operator后面接需要重载的操作符符号。

注意:

  1. 不能通过连接其他符号来创建新的操作符:比如operator@。(需要是C/C++语法中存在)
  2. 重载操作符必须有一个类类型或枚举类型的操作数。(不能去重载运算符改变内置类型的行为) -> 其实要真那么搞也可以,但是很无聊,没什么实用的
  3. 用于内置类型的操作符,重载后其含义不能改变。-> 例如内置的整型+,不能改变其含义
  4. 作为类成员的重载函数时,函数有一个默认的形参this,限定为第一个形参。
  5. sizeof 、:: 、.* 、?: 、. 这5个运算符不能重载。
  6. 并不是运算符都是需要重载的,需要看是否有存在的意义,参数部分需要对应顺序
// 来个实际例子
class Date
{
public:Date(int year = 0, int month = 1, int day = 1){_year = year;_month = month;_day = day;}void Print(){cout << _year << "年" << _month << "月" << _day << "日" << endl;}// 注意此时该函数的第一个形参默认为this指针bool operator==(const Date& d)// 运算符重载函数{return _year == d._year&&_month == d._month&&_day == d._day;}
private:int _year;int _month;int _day;
};int main()
{Date d1(2024, 9, 22);Date d2 = d1;// 注意优先级cout << (d1 == d2) << endl; // 1cout << d1.operator==(d2) << endl; // 与上一条语句等价return 0;
}

  显然第一种 d1 == d2 这种形式相当明了,就好像Date真的是我们的内置类型一样,其实说白了,还是编译器帮我们化成了第二种形式,不信我们可以看下汇编形式:

在这里插入图片描述

还是那句话,当你觉得轻松的时候,总是有人为你负重前行

赋值运算符重载

 先上代码:

class Date
{
public:Date(int year = 0, int month = 1, int day = 1) // 构造函数{_year = year;_month = month;_day = day;}Date& operator=(const Date& d) // 赋值运算符重载函数{if (this != &d) // 防止会有 d1 = d1 这样自己赋值给自己{_year = d._year;_month = d._month;_day = d._day;}return *this;}void Print()// 打印函数{cout << _year << "年" << _month << "月" << _day << "日" << endl;}
private:int _year;int _month;int _day;
};

我们要注意以下几点:

  1. 参数类型设置为引用,并用const进行修饰 -> 由于是自定义类型传参,我们若是使用传值传参,会额外调用一次拷贝构造函数,所以函数的第二个参数最好使用引用传参(第一个参数是默认的this指针,我们管不了)。并且我们也不改变它,那就用 const 来修饰
  2. 函数的返回值使用引用返回 -> 本质上是为了支持连续赋值,所以必须要有个返回值,而且很显然是返回左操作数 d3 = d2 = d1; 所以我们在这里返回 this 指针,且因为此时出了函数作用域this指针指向的对象并没有被销毁,所以可以使用引用返回,又省了拷贝多余的资源消耗
  3. 一个类如果没有显示定义赋值运算符重载,编译器也会自动生成一个,完成对象按字节序的值拷贝 -> 没错,赋值运算符重载编译器也可以自动生成,并且也是支持连续赋值的。但是编译器自动生成的赋值运算符重载完成的是对象按字节序的值拷贝,例如d2 = d1,编译器会将d1所占内存空间的值完完全全地拷贝到d2的内存空间中去,类似于memcpy
// 请注意区分
Date d1(2024,9,22);
Date d2 = d1; // 拷贝构造
Date d3;
d3 = d1; // 赋值// 拷贝构造函数:用一个已经存在的对象去构造初始化另一个即将创建的对象
// 赋值运算符重载函数:在两个对象都已经存在的情况下,将一个对象赋值给另一个对象

赋值运算符不可重载为全局函数

  赋值运算符重载跟拷贝构造类似,如果不显式实现,编译器会生成一个默认的赋值运算符重载,此时用户再类外自己实现一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突,故而赋值运算符只能是类的成员函数(其他运算符函数可以重载为全局函数)

《C++ Primer》第5版P500有言:
在这里插入图片描述

默认生成赋值运算符重载对于内置类型与自定义类型处理方式:

  1. 内置类型成员变量直接赋值的
  2. 自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值

  同样的,我们有个深拷贝和浅拷贝的问题,方式还是跟拷贝构造方式一样,当涉及到动态资源申请的时候深拷贝,否则浅拷贝即可

前置++和后置++的重载

  这两个妙就妙在一样就只有一个操作符,一个操作符在前一个在后

C++给出了它的解决方案:

//++d1
Date& operator++()
{_day += 1;return *this;
}//d1++
Date operator++(int)
{Date temp(*this);_day += 1;return temp;		
}

请注意,后置++重载函数中的参数int没有实际作用,只是为了与前置++构成函数重载,以便区分

二、const修饰成员函数

  将const修饰的 “成员函数” 称之为 const 成员函数,const修饰类成员函数,实际修饰改成员隐含的 this 指针,表明在该成员函数中不能对类的任何成员进行修改,如图:
在这里插入图片描述
在讲解具体的实用场景前,我们还可以先来看看这四个问题,答案和解释我都会相应给出:

  1. const对象可以调用非const成员函数吗?
  2. 非const对象可以调用const成员函数吗?
  3. const成员函数内可以调用其他的非const成员函数吗?
  4. 非const成员函数内可以调用其他的const成员函数吗

答案是:不可以、可以、不可以、可以

解释:
5. 非const成员函数,即成员函数的this指针没有被const所修饰,我们传入一个被const修饰的对象,用没有被const修饰的this指针进行接收,属于权限的放大,函数调用失败
6. const成员函数,即成员函数的this指针被const所修饰,我们传入一个没有被const修饰的对象,用被const修饰的this指针进行接收,属于权限的缩小,函数调用成功
7. 在一个被const所修饰的成员函数中调用其他没有被const所修饰的成员函数,也就是将一个被const修饰的this指针的值赋值给一个没有被const修饰的this指针,属于权限的放大,函数调用失败
8. 在一个没有被const所修饰的成员函数中调用其他被const所修饰的成员函数,也就是将一个没有被const修饰的this指针的值赋值给一个被const修饰的this指针,属于权限的缩小,函数调用成功

权限可以平移,也可以缩小,但是不可以放大

好,我们接下来来看以下代码:

// Print()成员函数没有被const修饰
int main()
{Date d1(2024, 9, 22);d1.Print(); // right,权限平移const Date d2(2024, 9, 22);d2.Print(); // err,权限放大return 0;
}

  但是并非所有函数都需要加上 const 修饰的!如果对成员变量进行读写访问的函数,不能加上 const ,另外,const修饰成员函数是修饰this指针的,那么 流插入>> 与 流提取<< 不是在类中实现,没有隐含的this指针,不能使用 const 修饰

三、取地址及const取地址操作符重载

  这两个默认成员函数一般不用重新定义,编译器会默认生成的,无需你多虑

class Date
{
public:Date* operator&(){return this;}const Date* operator&() const{return this;}
private:int _year; int _month; int _day; 
};

四、日期类的实现

 学完了这6个默认成员函数,我们来写个日期类巩固一下吧:

class Date
{
public:// 构造函数Date(int year = 1900, int month = 1, int day = 1);// 打印函数void Print() const;// 日期+=天数Date& operator+=(int day);// 日期+天数Date operator+(int day) const;// 日期-=天数Date& operator-=(int day);// 日期-天数Date operator-(int day) const;// 前置++Date& operator++();// 后置++Date operator++(int);// 前置--Date& operator--();// 后置--Date operator--(int);// 日期的大小关系比较bool operator>(const Date& d) const;bool operator>=(const Date& d) const;bool operator<(const Date& d) const;bool operator<=(const Date& d) const;bool operator==(const Date& d) const;bool operator!=(const Date& d) const;// 日期-日期int operator-(const Date& d) const;// 析构,拷贝构造,赋值重载可以不写,使用默认生成的即可private:int _year;int _month;int _day;
};

构造函数

// 获取某年某月的天数
inline int GetMonthDay(int year, int month)
{// 数组存储平年每个月的天数static int dayArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };int day = dayArray[month];if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){//闰年2月的天数day = 29;}return day;
}
// 构造函数
Date::Date(int year, int month, int day)
{// 检查日期的合法性if (year >= 0&& month >= 1 && month <= 12&& day >= 1 && day <= GetMonthDay(year, month)){_year = year;_month = month;_day = day;}else{// 严格来说抛异常更好cout << "非法日期" << endl;cout << year << "年" << month << "月" << day << "日" << endl;}
}

其中,我们注意一下这个GetMonthDay函数:

  1. 该函数可能被多次调用,所以我们最好将其设置为内联函数
  2. 函数中存储每月天数的数组最好是用static修饰,存储在静态区,避免每次调用该函数都需要重新开辟数组
  3. 逻辑与应该先判断 month == 2 是否为真,因为当不是2月的时候我们不必判断是不是闰年,短路判断

日期 += 天数

  因为出了作用域对象还存在,于是我们用引用返回
逻辑如下:
 1.若日已满,则日减去当前月的天数,月加一。
 2.若月已满,则将年加一,月置为1

// 日期 += 天数
Date& Date::operator+=(int day)
{if (day<0){// 复用operator-=*this -= -day;}else{_day += day;// 日期不合法,通过不断调整,直到最后日期合法为止while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if (_month > 12){_year++;_month = 1;}}}return *this;
}

日期 + 天数

  因为返回对象的值不变,但我们要返回变化后的值,于是就可以通过复用+=、创建临时变量tmp来解决,因为tmp出了作用域就销毁,于是我们用传值返回

// 日期 + 天数
Date Date::operator+(int day) const
{Date tmp(*this);// 拷贝构造tmp,用于返回// 复用operator+=tmp += day;return tmp;
}

日期 -= 天数

逻辑如下:
 1.若日为负数,则月减一。
 2.若月为0,则年减一,月置为12。
 3.日加上当前月的天数

// 日期 -= 天数
Date& Date::operator-=(int day)
{if (day < 0){// 复用operator+=*this += -day;}else{_day -= day;// 日期不合法,通过不断调整,直到最后日期合法为止while (_day <= 0){_month--;if (_month == 0){_year--;_month = 12;}_day += GetMonthDay(_year, _month);}}return *this;
}

日期 - 天数

 跟日期 + 天数类似,也是复用

// 日期-天数
Date Date::operator-(int day) const
{Date tmp(*this);// 拷贝构造tmp,用于返回// 复用operator-=tmp -= day;return tmp;
}

日期类的大小比较

 这里,我们将充分发挥复用的智慧!

日期类 > 日期类

逻辑:年大则大,月大则大,年月相等比日

bool Date::operator>(const Date& d) const
{if (_year > d._year){return true;}else if (_year == d._year){if (_month > d._month){return true;}else if (_month == d._month){return _day > d._day;}}return false;
}

日期类 == 日期类

逻辑:年月日均相等即为真

bool Date::operator==(const Date& d) const
{return _year == d._year&&_month == d._month&&_day == d._day;
}

日期类 >= 日期类

逻辑:复用前面两个

bool Date::operator>=(const Date& d) const
{return *this > d || *this == d;
}

日期类 < 日期类

逻辑:>= 的反面就是 <

bool Date::operator<(const Date& d) const
{return !(*this >= d);
}

日期类 <= 日期类

逻辑:> 的反面就是 <=

bool Date::operator<=(const Date& d) const
{return !(*this > d);
}

日期类 != 日期类

逻辑:== 的反面就是 !=

bool Date::operator!=(const Date& d) const
{return !(*this == d);
}

日期类 - 日期类

 其实也就是算两个日期之差,它还是有点意义的

试想一下,假如你未来结婚,结婚到一半,新娘子问你我们几年几月几日遇见的?
你早有准备,一下就回答上来
突然,新娘子还不死心,问你遇见当天离今天一共经历多少天?
你就可以说:“不急,我先跑个程序”
这就是日期类 - 日期类的一个实际场景运用

有两种思路,请听我细细道来:

 方法一:所谓日期 - 日期,即计算传入的两个日期相差的天数。我们只需要让较小的日期的天数一直加一,直到最后和较大的日期相等即可,这个过程中较小日期所加的总天数便是这两个日期之间差值的绝对值。若是第一个日期大于第二个日期,则返回这个差值的正值,若第一个日期小于第二个日期,则返回这个差值的负值,这很容易,设置一个判别变量 flag 即可

// 日期-日期
int Date::operator-(const Date& d) const
{Date max = *this;// 假设第一个日期较大Date min = d;// 假设第二个日期较小int flag = 1;// 此时结果应该为正值if (*this < d){// 假设错误,更正max = d;min = *this;flag = -1;// 此时结果应该为负值}int n = 0;// 记录所加的总天数while (min != max){min++;// 较小的日期++n++;// 总天数++}return n*flag;
}

 方法二:所谓“年、月、日”,不过也是一种进位的方式,那我们可以全把数堆给“日”这个位,先将年等同,再将月等同,最后直接将两个日期的“日”位相减即可,只需要注意返回的是正值还是负值

int Date::operator-(const Date& d)
{Date greD = (*this) > d ? *this : d;Date smlD = (*this) < d ? *this : d;while (greD._year > smlD._year) {if (isLeapYear(greD._year - 1)) greD._day += 366;else greD._day += 365;greD._year -= 1;}while (greD._month > smlD._month) {greD._month -= 1;greD._day += GetMonthDay(greD._year, greD._month);}while (greD._month < smlD._month) {greD._month += 1;greD._day -= GetMonthDay(greD._year, greD._month);}int ret = greD._day - smlD._day;return *this > d ? ret : -ret;
}

五、流插入流提取运算符重载

  这个比较困难,有一些不懂的概念可以暂且放一下

  其实,我们平时说cout、cin能自动识别类型,本质上就是因为重载,cout属于ostream类,cin属于istream类
在这里插入图片描述
  假如我们 重载运算符<< 为成员函数,隐含的 this 指针占用第一个参数的位置,Date必须是左操作数,使用时候d1<<cout 是不符合我们的习惯的

  于是,我们要将其重载为全局函数,并且把ostream& out放在第一个位置!但是又引出了另一个问题:类外不能访问类中的私有成员,如果将私有权限放开,就缺乏安全性,对此C++中有友元,接下来我们会涉及到,这里就使用下,虽然这个全局函数不在类中,但是可以访问私有成员函数

//友元,告诉该类这两个全局函数是我们的朋友,允许使用私有成员(在类中)friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);ostream& operator<<(ostream& out, const Date& d)
{out << d._year << "" << d._month << "" << d._day << "" << endl;return out;
}istream& operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;return in;
}

总结

  哈哈,这个中篇终于结束了,想不到吧,学Cpp的第一个大内容就如此困难!
  还有个下篇呢,继续加油吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1542452.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

device靶机详解

靶机下载地址 https://www.vulnhub.com/entry/unknowndevice64-1,293/ 靶机配置 主机发现 arp-scan -l 端口扫描 nmap -sV -A -T4 192.168.229.159 nmap -sS -Pn -A -p- -n 192.168.229.159 这段代码使用nmap工具对目标主机进行了端口扫描和服务探测。 -sS&#xff1a;使用…

AI 智能名片链动 2+1 模式商城小程序中的体验策略

摘要&#xff1a;本文探讨了在 AI 智能名片链动 21 模式商城小程序中&#xff0c;体验策略如何服务于用户体验&#xff0c;以及与产品策略的区别。重点分析了该小程序如何通过关注用户在使用过程中的流畅度、视觉体感等方面&#xff0c;实现“让用户用得爽”的目标&#xff0c;…

华为HarmonyOS地图服务 1 -- 如何实现地图呈现?

如何使用地图组件MapComponent和MapComponentController呈现地图&#xff0c;效果如下图所示。 MapComponent是地图组件&#xff0c;用于在您的页面中放置地图。MapComponentController是地图组件的主要功能入口类&#xff0c;用来操作地图&#xff0c;与地图有关的所有方法从此…

【小程序】微信小程序课程 -1 安装与配置

目录 1 微信小程序概述 1.1 什么是微信小程序 1.2 注册微信小程序账号 1.3 微信小程序配置 1.4 小程序开发流程 1.5 小程序成员 2、创建微信小程序项目 2.1 创建项目流程 2.2 创建项目 2.3 本地开发支持http 3 项目目录结构 3.1项目目录结构 3.1.1 目录介绍 3.1.2…

爬虫过程 | 蜘蛛程序爬取数据流程(初学者适用)

蜘蛛程序&#xff08;也称网络爬虫&#xff0c;是搜索引擎的重要组成部分&#xff09; 主要功能&#xff1a;遍历互联网&#xff0c;抓取网站信息并建立索引&#xff0c;便于用户在搜索引擎中检索到最新的网页内容工作原理&#xff1a;从初始网站页面的URL开始&#xff0c;发送…

Windows 配置docker和ubuntu系统

windos10 配置docke时&#xff0c;无意间发现wsl功能挺好用&#xff0c;而且是和docker 的linux容器连通的。 记录一下解决的几个问题 error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.40/images/json: open //./pipe/docker_engine: The system cannot …

【Docker】基于docker compose部署artifactory-cpp-ce服务

基于docker compose部署artifactory-cpp-ce服务 1 环境准备2 必要文件创建与编写3 拉取镜像-创建容器并后台运行4 访问JFog Artifactory 服务 1 环境准备 docker 以及其插件docker compose &#xff0c;我使用的版本如下图所示&#xff1a; postgresql 的jdbc驱动, 我使用的是…

Origin2021中文版详尽安装教程、附安装包下载

各位小伙伴们呀~ 今天给大家讲解下origin2021如何安装&#xff0c;相信你按照教程来操作&#xff0c;一定可以安装成功的。 废话不多少&#xff0c;正文开始~ tips&#xff1a;提前推出所有杀毒软件可不相干的软件&#xff0c;以免影响安装。 origin2021中文版安装教程 1.下…

御风于海,向阳而生!第六届中国互联网牛友会圆满落幕

近日&#xff0c;第六届中国互联网牛友会近日在大理实力喜来登酒店圆满落幕&#xff0c;本次盛会吸引了超过五百名行业精英与创业者共襄盛举。大会以“御风于海&#xff0c;向阳而生”为主题&#xff0c;聚焦于互联网出海、AI大模型、新媒体及WEB3等前沿科技与趋势&#xff0c;…

MySQL数据库select语句详细用法三(子查询及其select练习)

SELECT *FROM student2 WHERE age > (SELECT age FROM student2 WHERE NAME 欧阳丹丹) 首先解释一下括号中的代码&#xff0c;意思是在查询student2中的name为欧阳丹丹的人的名字&#xff0c;然后解释一下整个语句的意思&#xff1a;在括号中查询出来的字段中再次进行查询…

VUE3学习---【一】【从零开始的VUE学习】

目录​​​​​​​ 什么是Vue 渐进式框架 创建一个Vue应用 什么是Vue应用 使用Vue应用 根组件 挂载应用 模板语法 文本插值 原始HTML Attribute绑定 简写 同名简写 布尔型Attribute 动态绑定多个值 使用JavaScript表达式 仅支持表达式 指令 Directives 指令…

QString 构建SQL语句可以往数据库中添加“\n“字符串

网上找了很多案例关于怎么样能在Mysql数据库中插入带\n的字符串&#xff0c;如图&#xff1a; 本以为很容易的一件事&#xff0c;没想到思考了半天&#xff0c;在这里记录一下&#xff0c;以为\n是转义字符的原因&#xff0c;所以并不是我想的那么简单。网上有用R&#xff08;“…

【算法业务】互联网风控业务中的拒绝推断场景算法应用分享(涉及半监督算法、异常检测、变分自编码、样本权重自适应调整、迁移学习等)

1. 业务目标和任务描述 该项目是很早期的一个工作&#xff0c;属于互联网信贷风控场景&#xff0c;研究并应用信贷中的拒绝推断任务&#xff0c;处理方式也许对于目前的一些业务还有参考意义&#xff0c;因此这里做下分享。拒绝推断是指在信贷业务中&#xff0c;利用已知的接受…

《2024 年全球人工智能趋势报告》:GPU、数据架构依然是巨大挑战

导语&#xff1a;对于众多行业用户而言&#xff0c;了解人工智能如何改变行业、如何利用人工智能保持领先地位&#xff0c;已成为一道时代的必答题。全球著名调研机构WEKA近日正式发布《2024 年全球人工智能趋势报告》&#xff0c;该报告基于全球1500名人工智能决策者的深度调查…

【项目】基于 Huffman 算法实现文件压缩

摘要&#xff1a;记录通过学习Huffman算法自主实现简单的文件压缩程序的过程。 什么是文件压缩 在古诗词中&#xff0c;这种信息的高度浓缩体现得淋漓尽致。例如王维的《使至塞上》中的名句 “ 大漠孤烟直&#xff0c;长河落日圆 ”。仅仅十个字&#xff0c;却描绘出了一幅极为…

MoveIt控制机械臂的运动实现——机器人抓取系统基础系列(二)

文章目录 概要1 用户接口和代码案例2 不同的规划类型2.1 关节空间规划2.2 工作空间规划2.3 笛卡尔空间规划 3 MoveIt运行实操4 相关资料推荐小结 概要 MoveIt为开发者提供了针对机械臂的集成化开发平台&#xff0c;由一系列操作相关的功能包组成&#xff0c;包括运动规划、操作…

从 Affine Particle-In-Cell (APIC) 到 Material Point Method (MPM 物质点法)

APIC与MPM Particle-In-Cell (PIC)Affine Particle-In-Cell (APIC)Material Point Method (MPM)关于边界投影等额外操作 Material Point Method (MPM 物质点法)是一种混合欧拉-拉格朗日视角物理仿真方法。 欧拉视角即网格视角&#xff0c;将空间划分为网格&#xff0c;通过表示…

从一到无穷大 #35 Velox Parquet Reader 能力边界

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言源码分析功能描述功能展望 引言 InfluxDB IOX这样完全不使用索引&#xff0c;只…

JavaEE: 深入探索TCP网络编程的奇妙世界(四)

文章目录 TCP核心机制TCP核心机制四: 滑动窗口为啥要使用滑动窗口?滑动窗口介绍滑动窗口出现丢包咋办? TCP核心机制五: 流量控制 TCP核心机制 书接上文~ TCP核心机制四: 滑动窗口 为啥要使用滑动窗口? 之前我们讨论了确认应答策略,对每一个发送的数据段,都要给一个ACK确…

centos7下openssh升级方法(编译安装)

注意&#xff1a; 首先打开两个或以上的shell连接&#xff0c;因为在升级过程中如果升级失败会导致不发新建shell连接&#xff1b;升级后使用xshell6,7连接&#xff0c;openssh版本对应修改&#xff0c;下载地址&#xff1a; https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/por…