当前位置: 首页 > news >正文

C++(14):重载运算与类型转换

当运算符被用于类类型的对象时,允许我们为其指定新的含义;同时,也能自定义类类型之间的转换规则。和内置类型的转换一样,类类型转换隐式地将一种类型的对象转换成另一种我们所需类型的对象。

当运算符作用于类类型的运算对象时,可以通过运算符重载重新定义该运算符的含义。

基本概念

重载的运算符是具有特殊名字的函数:它们的名字由关键字operator 和其后要定义的运算符号共同组成。和其他函数一样,重载的运算符也包含返回类型、参数列表以及函数体

重载运算符函数的参数数量与该运算符作用的运算对象数量一样多。除了重载的函数调用运算符 operator()之外,其他重载运算符不能含有默认实参。

当一个重载的运算符是成员函数时,this 绑定到左侧运算对象。成员运算符函数的(显式)参数数量比运算对象的数量少一个。
在这里插入图片描述
通常情况下,不应该重载逗号、取地址、逻辑与和逻辑或运算符。

调用重载运算符的两种方式:
1.直接使用运算符。如 data1+data2;data1+=data2+ 是非成员函数,+= 是类的成员函数,两种都可以直接使用。
2.向调用普通函数一样调用运算符函数。如 operator+(data1,data2)data1.operator+=(data2)
注意运算符函数的函数名是 operator 加运算符本身。

使用与内置类型一致的含义

  1. 如果类执行IO操作,则定义移位运算符使其与内置类型的IO保持一致。
  2. 如果类的某个操作是检查相等性,则定义 operator==;如果类有了operator==,意味着它通常也应该有operator!=
  3. 如果类包含一个内在的单序比较操作,则定义 operator<;如果类有了operator<,则它也应该含有其他关系操作。
  4. 重载运算符的返回类型通常情况下应该与其内置版本的返回类型兼容:逻辑运算符和关系运算符应该返回bool,算术运算符应该返回一个类类型的值,赋值运算符和复合赋值运算符则应该返回左侧运算对象的一个引用。

赋值运算符的行为与复合版本的类似:赋值之后,左侧运算对象和右侧运算对象的值相等,并且运算符应该返回它左侧运算对象的一个引用。重载的赋值运算应该继承而非违背其内置版本的含义。

运算符选择作为成员或者非成员

  1. 赋值(=)、下标([])、调用(())和成员访问箭头(->)运算符必须是成员。
  2. 复合赋值运算符一般来说应该是成员,但并非必须这一点与赋值运算符略有不同。
  3. 改变对象状态的运算符或者与给定类型密切相关的运算符,如递增、递减和解引用运算符,通常应该是成员。
  4. 具有对称性的运算符可能转换任意一端的运算对象,例如算术、相等性、关系和位运算符等,因此它们通常应该是普通的非成员函数。

输入和输出运算符

重载输出运算符 <<

通常情况下,输出运算符的第一个形参是一个非常量 ostream 对象的引用。
之所以 ostream 是非常量是因为向流写入内容会改变其状态;而该形参是引用是因为我们无法直接复制一个ostream对象。
第二个形参一般来说是一个常量的引用,该常量是我们想要打印的类类型。
第二个形参是引用的原因是我们希望避免复制实参;而之所以该形参可以是常量是因为(通常情况下)打印对象不会改变对象的内容。
重载的 << 应该返回它的 ostream 形参。

通常,输出运算符应该主要负责打印对象的内容而非控制格式,输出运算符不应该打印换行符。
iostream 标准库兼容的输入输出运算符必须是普通的非成员函数,而不能是类的成员函数。但是应该声明为类的友元。

重载输出运算符 >>

通常情况下,输入运算符的第一个形参是运算符将要读取的流的引用,第二个形参是将要读入到的(非常量)对象的引用。该运算符通常会返回某个给定流的引用。
第二个形参之所以必须是个非常量是因为输入运算符本身的目的就是将数据读入到这个对象中。

输入运算符必须处理输入可能失败的情况,而输出运算符不需要。

 当流含有错误类型的数据时读取操作可能失败。当读取操作到达文件末尾或者遇到输入流的其他错误时也会失败。
if(is)//检查输入是否成功item. revenue = item.units_sold * price;
elseitem = Sales_data();//输入失败:对象被赋予默认的状态

如果在发生错误前对象已经有一部分被改变,则适时地将对象置为合法状态异常重要

算术和关系运算符

通常把算术和关系运算符定义成非成员函数以允许对左侧或右侧的运算对象进行转换,
因为这些运算符一般不需要改变运算对象的状态,所以形参都是常量的引用。

如果类同时定义了算术运算符和相关的复合赋值运算符,则通常情况下应该使用复合赋值来实现算术运算符。

相等运算符

相等运算符来检验两个对象是否相等。

设计准则:
1.将函数定义为 operator== 而不是一个普通的命名函数;
2.能判断一组给定对象中是否含有重复数据;
3.具有传递性;
4.如果定义了 operator==,那么也应该定义 operator1!=

关系运算符

定义了相等运算符的类也常常(但不总是)包含关系运算符。特别是,关联容器和一些算法要用到小于运算符,所以定义operator<

设计准则:
1.定义顺序关系,令其与关联容器中对关键字的要求一致;
2.如果类同时含有 == 运算符,则定义关系要与 ==一致。

赋值运算符

类可以定义除了拷贝赋值和移动赋值运算符以外的其他运算符使用别的类型作为右侧运算对象。

可以重载赋值运算符。不论形参的类型是什么,赋值运算符都必须定义为成员函数。

赋值运算符必定义为类的成员,复合赋值运算符通常情况下也应该这样做,但复合赋值运算符不非得是类的成员。这两类运算符都应该返回左侧对象的引用。

下标运算符

表示容器的类通常可以通过元素在容器中的位置访问元素,这些类一般会定义下标运算符operator[]
下标运算符必须是成员函数。

下标运算符通常以所访问元素的引用作为返回值,这样下标可以出现在赋值运算符的任意一端。

如果一个类包含下标运算符,则它通常会定义两个版本:一个返回普通引用,另一个是类的常量成员并且返回常量引用。

递增和递减运算符

C++ 并不要求递增和递减运算符必须是类的成员,但是因为它们改变的正好是所操作对象的状态,所以建议将其设定为成员函数。

对于内置类型,递增和递减运算符应该同时定义前置和后置版本。
前置版本返回递增或递减后的引用,后置版本返回修改前的副本。

class StrBlobPtri{
public://递增和递减运算符StrBlobPtr& operator++();	//前置运算符StrBlobPtr& operator--();//其他成员和之前的版本一致StrBlobPtr operator++(int) ;	//后置运算符StrBlobPtr operator--(int) ;//其他成员和之前的版本一致
};

成员访问运算符

迭代器类和智能指针类通常会用到运算符* 和箭头运算符 ->
箭头运算符必须是类的成员,箭头运算符一般通过调用解引用运算符来实现。
解引用运算符通常也是类的成员,但不必须的。

重载的箭头运算符必须返回类的指针或者自定义了箭头运算符的某个类的对象。

函数调用运算符

类重载函数调用运算符,就可以像使用函数一样使用该类的对象。

函数调用运算符必须是成员函数。一个类可以定义多个不同版本的调用运算符,相互之间应该在参数数量或类型上有所区别。

struct absInt{int operator()(int val)const {return val < 0 ? -val : val;}int i=-42;absInt absObj;//含有函数调用运算符的对象int ui = absObj(i);//将i传递给abs0bj .operator()
}

含有状态的函数对象类
和其他类一样,函数对象类除了operator()之外也可以包含其他成员。函数对象类通常含有一些数据成员,这些成员被用于定制调用运算符中的操作。

class PrintString {
public:PrintString(ostream &o =cout,char c=''):os(o), sep(c){}void operator()(const string &s)const{ os<<s<< sep; }
private:ostream &os;//用于写入的目的流char sep;//用于将不同输出隔开的字符
};

lambda 是函数对象

编写一个lambda后,编译器将该表达式翻译成一个未命名类的未命名对象。在lambda表达式产生的类中含有一个重载的函数调用运算符:

//根据单词的长度对其进行排序,对于长度相同的单词按照字母表顺序排序
stable_sort(words.begin(), words.end(),[](const string &a, const string &b){return a.size()< b.size();});//其行为类似下面类的一个未命名对象
class ShorterString {
public:bool operator() (const string &s1,const string &s2) const{return sl.sizeo< s2.size();}
};

默认情况下 lambda不能改变它捕获的变量。因此在默认情况下,由 lambda产生的类当中的函数调用运算符是一个const成员函数。如果lambda被声明为可变的,则调用运算符就不是const的了。

  • lambda 通过引用捕获变量时,由程序确保 lambda 执行时所引用的对象确实存在。因此,编译器可以直接使用该引用而无须再 lambda 产生的类中将其存储为数据成员;
  • lambda 通过值捕获变量时,产生的类必须为每个值捕获的变量建立对应的数据成员,同时创建构造函数,令其使用捕获的变量的值来初始化数据成员。

标准库定义的函数对象

标准库定义了一组表示算术运算符、关系运算符和逻辑运算符的类,每个类分别定义了一个执行命名操作的调用运算符。这些定义在头文件 functional 中。
在这里插入图片描述函数对象其实是一个函数对象类,表示运算符的函数对象类常用来替换算法中的默认运算符。
标准库规定其函数对象对于指针同样适用。

可调用对象与 function

几种可调用的对象:函数、函数指针、lambda表达式、bind创建的对象以及重载了函数调用运算符的类。

和其他对象一样,可调用的对象也有类型,两个不同类型的可调用对象可能共享同一种调用形式
调用形式指明了调用返回的类型以及传递给调用的实参类型。一种调用形式对应一个函数类型。

int (int, int)
//是一个函数类型,它接受两个int、返回一个int。

不同类型可能具有相同的调用形式

//普通函数
int add(int i, int j) { return i + j;}
// lambda,其产生一个未命名的函数对象类
auto mod = [](int i, int j){return i %j;};
//函数对象类
struct divide{int operator()(int denominator, int divisor){return denominator / divisor;}
};

三个可调用对象具有相同的调用形式 int(int,int),但是他们三个不是同一类型。

标准库 function 类型
在这里插入图片描述不能直接将重载函数的名字存入 function 类型的对象中,但是可以存储指向确定重载版本的函数指针。

function<int(int, int)> f1 = add;   //add 是个函数指针
funciton<int(int, int)> f2 = divide();  //divide() 返回一个函数对象的对象。
function<int (int,int)> f3 =[](int i, int j)// lambda{return i*j;};cout <<f1(4,2)<< endl;//打印6
cout <<f2(4,2)<<endl;//打印2
cout <<f3(4,2)<<endl;//打印8

不能(直接)将重载函数的名字存入 function类型的对象中,会产生二义性问题

int add(int i, int j){return i+j;}
Sales_data add(const Sales_data&,const Sales_data&);
map<string, function<int (int, int)>> binops;
binops.insert( {"+",add} );//错误:哪个add?

解决二义性问题:1.存储函数指针,而不是函数的名字; 2.使用 lambda 指定函数版本。

//1.存储函数指针
int(*fp)(int,int) = add;//指针所指的add是接受两个int的版本
binops.insert ({"+",fp) );//正确:fp指向一个正确的add版本//2.lambda
binops.insert({"+"[](int a,int b){return add (a, b);}});

重载、类型转换与运算符

转换构造函数和类型转换运算符共同定义了类类型转换,这样的转换有时也称为用户定义的类型转换。

类型转换运算符

类型转换运算符是类的一种特殊成员函数,负责将一个类类型转换成其他类型。

operator type() const;

类类型转换运算符可以面向能作为函数的返回类型的任意类型(除了void )进行定义。
因此,不能转换成数组或者函数类型,但允许转换成指针(包括数组指针以及函数指针)或者引用类型。

类型转换运算符既没有显式的返回类型,也没有形参,而且必须定义成类的成员函数。类型转换运算符通常不应该改变待转换对象的内容,因此,类型转换运算符一般被定义成const成员。

class SmallInt{
public:SrmallInt (int i=0) : val (i){if(i<0 || i > 255)throw std: :out_of_range ("Bad SmallInt value");}operator int() const {return val;}
private:std::size_t val;
};//SmallInt 类既定义了向类类型的转换,也定义了从类类型向其他类型的转换。其中,构造函数将算术类型的值转换成SmallInt对象,而类型转换运算符将SmallInt对象转换成int:
SmallInt si;
si = 4;//首先将4隐式地转换成 SmallInt,然后调用 SmallInt::operator=
si + 3;//首先将si隐式地转换成 int,然后执行整数的加法

显式的类型转换运算符

class SmallInt {
public://编译器不会自动执行这一类型转换explicit operator into const{return val;}//其他成员与之前的版本一致
};//和显式的构造函数一样,编译器(通常)也不会将一个显式的类型转换运算符用于隐式类型转换:
SmallInt si=3;//正确:SmallInt的构造函数不是显式的
si +3;//错误:此处需要隐式的类型转换,但类的运算符是显式的
static_cast<int>(si) + 3;//正确:显式地请求类型转

当类型转换运算符是显式的时,也能执行类型转换,不过必须通过显式的强制类型转换才可以。

转换为 bool:向 bool 类型的转换一般都用于条件部分,因此 operator bool() 一般定义成 explicit 的。

避免有二义性的类型转换

如果类中包含一个或多个类型转换,则必须确保在类类型和目标类型之间只存在唯一一种转换方式。否则代码将很可能会具有二义性。

有两种情况可能产生多重转换路径:
1.两个类提供相同的类型转换。例如,A 类定义了一个接受 B 类对象的转换构造函数,同时 B 类定义了一个转换目标是 A 类的类型转换运算符;
2.定义了多个转换规则。

注意:除了显式地向bool类型的转换之外,应该尽量避免定义类型转换函数并尽可能地限制那些“显然正确”的非显式构造函数。
1.不要令两个类执行相同的类型转换;
2.避免转换目标是内置算术类型的类型转换。定义了一个转换算术类型的类型转换时,不要再定义接受算术类型的重载运算符,也不要定义转换到多种算术类型的类型转换。

函数匹配与重载运算符

重载的运算符也是重载的函数。
调用一个命名的函数时,具有该名字的成员函数和非成员函数不会彼此重载。因为用来调用命名函数的语法形式对于成员函数和非成员函数来说是不相同的。

a.operatorsym(b); // a有一个 operatorsym成员函数
operatorsym(a, b);// operatorsym是一个普通函数

表达式中运算符的候选函数集既应该包括成员函数,也应该包括非成员函数。

如果对同一个类既提供了转换目标是算术类型的类型转换,也提供了重载的运算符,则将会遇到重载运算符与内置运算符的二义性问题。

SmallInt sl,s2;
Smal1Int s3 = s1 + s2;//使用重载的operator+
int i = s3 + 0;//二义性错误

重要术语

调用形式:表示一个可调用对象的接口。在调用形式中包括返回类型以及一个实参类型列表,该列表在一对圆括号内,实参类型之间以逗号分隔。

类类型转换:包括由构造函数定义的从其他类型到类类型的转换以及由类型转换运算符定义的从类类型到其他类型的转换。只接受单独一个实参的非显式构造函数定义了从实参类型到类类型的转换;而类型转换运算符则定义了从类类型到某个指定类型的转换。

类型转换运算符:是类的成员函数,定义了从类类型到其他类型的转换。类型转换运算符必须是它要转换的类的成员,并且通常被定义为常量成员。这类运算符既没有返回类型,也不接受参数。它们返回一个可变为转换运算符类型的值,也就是说,operator int返回一个intoperator string返回一个 string,依此类推。

重载的运算符:重定义了某种内置运算符的含义的函数。重载的运算符函数含有关键字operator,之后是要定义的符号。重载的运算符必须含有至少一个类类型的运算对象。重载运算符的优先级、结合律、运算对象数量都与其内置版本一致。

相关文章:

C++(14):重载运算与类型转换

当运算符被用于类类型的对象时&#xff0c;允许我们为其指定新的含义&#xff1b;同时&#xff0c;也能自定义类类型之间的转换规则。和内置类型的转换一样&#xff0c;类类型转换隐式地将一种类型的对象转换成另一种我们所需类型的对象。 当运算符作用于类类型的运算对象时&a…...

【深度学习】基于图形的机器学习:概述

一、说明 图神经网络&#xff08;GNN&#xff09;在数据科学和机器学习中越来越受到关注&#xff0c;但在专家圈之外仍然知之甚少。为了掌握这种令人兴奋的方法&#xff0c;我们必须从更广泛的图形机器学习&#xff08;GML&#xff09;领域开始。许多在线资源谈论GNN和GML&…...

内存泄漏是什么?有什么危害

内存泄漏是什么&#xff1f;有什么危害 1. 前言1.内存泄漏是什么&#xff1f;2. 为什么会发生内存泄漏3. 内存泄漏的危害4. 总结 1. 前言 在各种项目开发中&#xff0c;内存泄漏是一个很严重的问题。对资源管理、性能优越、系统稳定性&#xff0c;以及是否安全产生极大印象。本…...

【项目设计】基于负载均衡的在线oj平台

目录 一、项目介绍 二、开发环境以及技术 三、概要设计 四、关键算法 五、项目演示 六、代码实现 一、项目介绍 该项目是基于负载均衡的在线oj&#xff0c;模拟平时刷题网站&#xff08;leetcode和牛客&#xff09;写的一个在线判题系统 项目主要分为五个模块&#xff…...

生产环境Session解决方案、Session服务器之Redis

目录 一、服务器配置 二、安装nginx 三、安装配置Tomcat&#xff1a; 四、配置session Session服务器之Redis Redis与Memcached的区别 安装部署redis 一、服务器配置 IP地址 主机名 软件包列表 192.168.100.131 huyang1 nginx 192.168.100.133 huyang3 JDK Tomca…...

SPECjvm2008_1_01 openjdk8 x86_64 ARM64 运行时长、成绩 Run is valid, but not compliant

i5-9600k 架构&#xff1a; x86_64CPU 运行模式&#xff1a; 32-bit, 64-bitAddress sizes: 39 bits physical, 48 bits virtual字节序&#xff1a; Little Endian CPU: 6在线 CPU 列表&#xff1a; …...

安卓:百度地图开发(超详细)

一、百度地图介绍 百度地图SDK是一套供开发者使用的软件开发工具包&#xff08;SDK&#xff09;&#xff0c;用于在Android应用程序中集成和使用百度地图功能。通过使用百度地图SDK&#xff0c;开发者可以实现在自己的应用中显示地图、获取定位信息、进行搜索、导航等功能。 百…...

DDSv1.4规范(中文版)

实时数据分发 (DDS) V1.4 (2015-04-10正式发布) https://www.omg.org/spec/DDS/1.4/PDF http://www.omg.org/spec/DDS/20140501/dds_dcps.idl...

oracle,获取每日24*60,所有分钟数

前言&#xff1a; 为规范用户的时间录入&#xff0c;因此我们采用下拉的方式&#xff0c;让用户选择需要的时间&#xff0c;因此我们需要将一天24小时的时间拆分为类似00:00,00:01...23:00,23:01,23:59。因此我们需要生成24*601440行的下拉复选值。具体效果如下图所示。 思路 1…...

vue elementui table去掉滚动条与实现表格自动滚动且无滚动条

当table内容列过多时&#xff0c;可通过height属性设置table高度以固定table高度、固定表头&#xff0c;使table内容可以滚动。 现在需求是右侧滚动条不好看&#xff0c;需要去除滚动条&#xff0c;并隐藏滚动条所占列的位置。让他可以滚动但是不出现滚动条,不然即时隐藏了滚动…...

SDK命令行工具配置

SDK命令行工具配置 最早的Android SDK工具包&#xff0c;包含一些GUI的工具。 而在一些场景&#xff08;如打包&#xff09;只需要命令行工具时&#xff0c;下载 command-line tools 即可。 到 Android Studio下载页 &#xff0c;找到 Command line tools only 下载。 命令…...

【数字IC基础】竞争与冒险

竞争-冒险 1. 基本概念2. 冒险的分类3. 静态冒险产生的判断4. 毛刺的消除使用同步电路使用格雷码增加滤波电容增加冗余项&#xff0c;消除逻辑冒险引入选通脉冲 1. 基本概念 示例一&#xff1a; 如上图所示的这个电路&#xff0c;使用了两个逻辑门&#xff0c;一个非门和一个与…...

速成版-带您一天学完python自动化测试(selenium)

Selenium是一套web网站的程序自动化操作解决方案。我们通过编写自动化程序&#xff0c;使得自动完成浏览器界面的相关操作&#xff0c;除了能够自动化的完成相关操作&#xff0c;还能从web页面获取相关信息&#xff0c;然后通过程序进行分析处理&#xff0c;本质上就是提升从网…...

windows 删除无法删除的文件

有两种原因&#xff1a; 文件被占用文件无权限 解决方案 通用解决方案是进入安全模式进行删除 安全模式&#xff1a; 不会启动非必要的进程有最高的系统权限 进入系统配置 安全引导&#xff0c;重启 删除文件 修改系统配置为正常启动 重启...

FFmpeg[7] - FFmpeg之预设编码参数preset

目录 前言 正文 一、定义与作用 二、取值范围 三、枚举值 四、使用实例...

CVPR2023新作:3D视频物体检测

Title: 3D Video Object Detection With Learnable Object-Centric Global Optimization Affiliation: 中国科学院自动化研究所 (Institute of Automation, Chinese Academy of Sciences)&#xff0c;中国科学院大学人工智能学院 (School of Artificial Intelligence, Univers…...

Keepalived热备、Keepalived+LVS、HAProxy监控及后端服务器健康检查、负载均衡调度器对比

day02 day02KeepAlived高可用集群配置高可用的web集群监控本机80端口&#xff0c;实现主备切换实现原理实施配置高可用、负载均衡的web集群配置高可用、负载均衡HAProxy配置haproxy负载均衡调度器比较LVS&#xff08;Linux Virtual Server&#xff09;NginxHAProxy KeepAlive…...

用Vue开发仿旅游站webapp项目总结 (上)

写着写着发现会写不少内容... 全部写在一篇文章里感觉太多了不方便看&#xff0c;所以分为上下篇吧... 下篇写完啦&#xff0c;感兴趣的朋友可以继续关注~ > 用Vue开发仿旅游站webapp项目总结 &#xff08;下&#xff09; 温馨提示 此文章&#xff0c;仅是做完项目后的个人…...

【Koa】[NoSQL] Koa中相关介绍和使用Redis MongoDB增删改查

目录 NoSQL非关系型数据库关系型数据库&#xff08;RMDB&#xff09;介绍非关系型数据库&#xff08;NoSQL&#xff09;介绍Redis & MongoDB 在 Koa 中使用 Redis (了解)Redis 的安装和使用在 Koa 中连接 和 调用 Redis 在 Koa 中使用 MongoDBMongoDB 的安装MongoShell 操作…...

【JS 阻止滑动穿透】

在实现阻止滑动穿透时&#xff0c;可以使用以下方法之一&#xff1a; 使用 CSS 属性 overflow: hidden 来禁止页面滚动。 body {overflow: hidden; }使用 JavaScript 监听滚动事件并阻止默认行为。 document.addEventListener(touchmove, function(e) {e.preventDefault(); …...

编译原理

目录 一&#xff0c;基本概念 二&#xff0c;词法分析 三&#xff0c;自上而下推导 一&#xff0c;基本概念 二&#xff0c;词法分析 三&#xff0c;自上而下推导...

项目播报 | 新基德携手璞华易研PLM,打造企业新一代研发管理平台

近日&#xff0c;“新基德PLM&#xff08;Product Lifecycle Management&#xff0c;产品生命周期管理&#xff09;项目”在新基德&#xff08;深圳&#xff09;电子有限公司&#xff08;以下简称&#xff1a;新基德&#xff09;正式启动。新基德是一家集手机研发、生产、销售、…...

elementui el-table 封装表格

ps: 1.3版本 案例&#xff1a; 完整代码&#xff1a; 可直接复制粘贴&#xff0c;但一定要全看完&#xff01; v-slot"scopeRows" 是vue3的写法&#xff1b; vue2是 slot-scope"scope" <template><!-- 简单表格、多层表头、页码、没有合并列行…...

集合--collections

一、collections概述 Collections和Arrays、Objects-一样&#xff0c;都是一种针对性的工具类, Arrays是针对数组&#xff0c;Objects是针对Object, 而Colections则是针对集合的一种工具类&#xff0c;里面提供了大量的方便我们操作集合的方法: //往集合中添加一些元素。 p…...

go使用gin结合jwt做登录功能

1、安装gin go get -u github.com/gin-gonic/gin 2、安装session go get github.com/gin-contrib/sessions 3、安装JWT鉴权 go get "github.com/golang-jwt/jwt/v4" 4、创建一个jwt的工具文件 package utilsimport ("errors""github.com/golan…...

【C++】开源:Boost网络库Asio配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Asio网络库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次…...

图像滤波器

图像噪声 • 图像噪声是图像在获取或是传输过程中受到随机信号干扰&#xff0c;妨碍人们对图像理解及分析处理 的信号。 • 图像噪声的产生来自图像获取中的环境条件和传感元器件自身的质量&#xff0c;图像在传输过程中产 生图像噪声的主要因素是所用的传输信道受到了噪声…...

【每日一题】2569. 更新数组后处理求和查询

【每日一题】2569. 更新数组后处理求和查询 2569. 更新数组后处理求和查询题目描述解题思路 2569. 更新数组后处理求和查询 题目描述 给你两个下标从 0 开始的数组 nums1 和 nums2 &#xff0c;和一个二维数组 queries 表示一些操作。总共有 3 种类型的操作&#xff1a; 操作…...

PLC的高端版本通常具有以下特点:

高速处理能力&#xff1a;高端PLC通常具有更快的处理速度和更高的运行频率&#xff0c;可以处理更复杂的控制逻辑和更多的输入/输出信号。 大容量存储&#xff1a;高端PLC通常具有更大的存储容量&#xff0c;可以保存更多的程序和数据&#xff0c;以满足更复杂的应用需求。 多种…...

Scrum敏捷开发项目管理和产品研发管理培训- Leangoo领歌

Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架。 这是一个两天的实训课程&#xff0c;面向研发管理者、项目经理、产品经理、研发团队等&#xff0c;旨在帮助学员全面系统地学习Scrum和敏捷开发, 帮助企业快速启动敏捷实施。 …...