从0到1入门C++编程——05 类和对象之运算符重载、继承

文章目录

  • 运算符重载
    • 1.加号运算符重载
    • 2.左移运算符重载
    • 3.递增运算符重载
    • 4.赋值运算符重载
    • 5.关系运算符重载
    • 6.函数调用运算符重载
  • 继承
    • 1.继承的基本语法及继承方式
    • 2.继承中的对象模型
    • 3.继承中构造函数和析构函数的顺序
    • 4.继承中同名成员的处理方式
    • 5.继承中同名静态成员处理方式
    • 6.继承多个父类
    • 7.菱形继承

运算符重载

运算符重载是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。

1.加号运算符重载

加减乘除运算符的重载是一样的,只需要将operator后面的符号换成相应的运算符即可,下面以加号运算符的重载为例。
成员函数重载+运算符。

#include <iostream>
#include <string>
using namespace std;

class Person
{
public:
	//成员函数重载+运算符
	Person operator+(Person &p)
	{
		Person temp;
		temp.a = this->a+p.a;
		temp.b = this->b+p.b;
		return temp;
	}
public:
	int a;
	int b;
};

int main()
{
	Person p1,p2;
	p1.a = 10;
	p1.b = 20;
	p2.a = 10;
	p2.b = 20;
	Person p3;
	p3 = p1 + p2;  //相当于 p3 = p1.operator+(p2);
	cout<<"p3.a="<<p3.a<<"  p3.b="<<p3.b<<endl;

	system("pause");
	return 0;
}

全局函数重载+运算符。

#include <iostream>
#include <string>
using namespace std;

class Person
{
public:
	int a;
	int b;
};

//全局函数重载+运算符
Person operator+(Person &p1,Person &p2)
{
	Person temp;
	temp.a = p1.a+p2.a;
	temp.b = p1.b+p2.b;
	return temp;
}

int main()
{
	Person p1,p2;
	p1.a = 10;
	p1.b = 20;
	p2.a = 10;
	p2.b = 20;
	Person p3;
	p3 = p1 + p2;  //相当于 p3 = operator+(p1,p2);
	cout<<"p3.a="<<p3.a<<"  p3.b="<<p3.b<<endl;

	system("pause");
	return 0;
}

2.左移运算符重载

重载左移运算符配合友元可以实现自定义数据类型的输出。
左移运算符重载不能在成员函数中实现,因为涉及到传参,cout应在类前面。
转到cout的定义处,其是一个ostream类型的变量。

__PURE_APPDOMAIN_GLOBAL extern istream cin, *_Ptr_cin;
__PURE_APPDOMAIN_GLOBAL extern ostream cout, *_Ptr_cout;

左移运算符重载的代码如下。

#include <iostream>
#include <string>
using namespace std;

class Person
{
	//全局函数作为友元访问私有属性
	friend ostream& operator<<(ostream &out,Person &p);
public:
	Person(int a,int b)
	{
		this->a = a;
		this->b = b;
	}
private:
	int a;
	int b;
};

//重载左移运算符
ostream& operator<<(ostream &out,Person &p)
{
	out<<"a="<<p.a<<" b="<<p.b;
	return out;
}

int main()
{
	Person p(10,20);
	cout<<p<<endl;  //直接输出对象,需要重载左移运算符才可以

	system("pause");
	return 0;
}

上面代码的运行结果如下图所示。
在这里插入图片描述

3.递增运算符重载

前置递增运算返回引用,后置递增运算返回值。
递增运算符重载的代码如下。

#include <iostream>
#include <string>
using namespace std;

class Person
{
	friend ostream& operator<<(ostream &out,Person p);
public:
	Person()
	{
		num = 0;
	}
	//重载前置++运算符
	Person& operator++()  //需要返回引用,这样每次递增操作都是对同一个对象
	{
		num++;
		return *this;
	}
	//重载后置++运算符
	Person operator++(int)  //占位参数用来区分前置++和后置++
	{
		Person temp = *this; //先返回以前值,再++,但是返回不能在++之前,因此需要先记录
		num++;
		return temp;
	}
private:
	int num;
};

//重载左移运算符
ostream& operator<<(ostream &out,Person p)
{
	out<<p.num;
	return out;
}

int main()
{
	Person p1,p2;
	cout<<"1.p1++="<<p1++<<endl;
	cout<<"2.p1="<<p1<<endl;
	cout<<"1.++p2="<<++p2<<endl;
	cout<<"2.p2="<<p2<<endl;

	system("pause");
	return 0;
}

上面代码的运行结果如下图所示。
在这里插入图片描述

4.赋值运算符重载

赋值运算符重载是为了实现涉及堆区内存的拷贝,要以深拷贝的形式实现,浅拷贝的方式在析构函数执行时会发生错误。
赋值运算符重载的代码如下。

#include <iostream>
#include <string>
using namespace std;

class Person
{
public:
	Person(int age)
	{
		this->age = new int(age);
	}
	
	//重载赋值运算符
	Person& operator=(Person &p)
	{
		//age = p.age;   //默认的重载内容,浅拷贝
		//先判断属性是否在堆区,如果在就先释放,再接收拷贝
		if(age != NULL)
		{
			delete age;
			age = NULL;
		}
		age = new int(*p.age);  //深拷贝实现
		return *this;   //为了实现连等赋值,需要返回自身而不能是void类型
	}

	//析构函数中释放堆区内存
	~Person()
	{
		if(age != NULL)
		{
			delete age;
			age = NULL;
		}
	}

	int *age;
};

void fun()   //需要在函数中测试,这样函数返回后就会调用析构函数
{
	Person p1(18);
	Person p2(20);
	Person p3(22);
	p3 = p2 = p1;
	cout<<"p1的年龄为:"<<*p1.age<<endl;
	cout<<"p2的年龄为:"<<*p2.age<<endl;
	cout<<"p3的年龄为:"<<*p3.age<<endl;
}

int main()
{
	fun();

	system("pause");
	return 0;
}

上面代码的运行结果如下图所示。
在这里插入图片描述

5.关系运算符重载

重载两个关系运算符,可以让两个自定义类型的对象进行对比。
关系运算符重载的代码如下。

#include <iostream>
#include <string>
using namespace std;

class Person
{
public:
	Person(string name,int age)
	{
		this->name = name;
		this->age = age;
	}
	
	//重载关系运算符
	bool operator==(Person &p)
	{
		if(name == p.name && age == p.age)
			return true;
		else
			return false;
	}

private:
	string name;
	int age;
};

void fun()   //需要在函数中测试,这样函数返回后就会调用析构函数
{
	Person p1("aaa",18);
	Person p2("bbb",20);
	Person p3("aaa",18);
	if(p1==p2)
		cout<<"p1和p2年龄和名字都相同!"<<endl;
	else
		cout<<"p1和p2不相同!"<<endl;
	if(p1==p3)
		cout<<"p1和p3年龄和名字都相同!"<<endl;
	else
		cout<<"p1和p3不相同!"<<endl;
}

int main()
{
	fun();

	system("pause");
	return 0;
}

上面代码的运行结果如下图所示。
在这里插入图片描述

6.函数调用运算符重载

函数调用运算符是 () ,由于重载后使用的方式像函数调用,因此称为仿函数,仿函数没有固定写法,非常灵活。
函数调用运算符重载的代码如下。

#include <iostream>
#include <string>
using namespace std;

class Person
{
public:
	//重载函数调用运算符
	void operator()(string s)
	{
		cout<<s<<endl;
	}
	void operator()(int a,int b)
	{
		cout<<"result = "<<a+b<<endl;
	}
};

void fun(string s) 
{
	cout<<s<<endl;
}

int main()
{
	Person p;
	p("Hello operator()!");  //重载函数调用运算符后调用
	fun("Hello fun()!");  //函数调用
	p(100,200); 
	Person()(10,20);   //匿名对象调用

	system("pause");
	return 0;
}

上面代码的运行结果如下图所示。
在这里插入图片描述


继承

1.继承的基本语法及继承方式

继承是面向对象的三大特性之一。
类与类之间存在特殊的关系,比如下面的类中,下级的成员除了拥有上一级的共性外,还有自己的特性。
在这里插入图片描述
这个时候可以使用继承,减少重复的代码,这也是通过继承带来的好处。
继承的语法:class 子类名 :继承方式(public等) 父类名
继承方式包括公共继承(public) 、保护继承(protected) 和私有继承(private) 。
父类也称基类,子类也称派生类。
派生类中的成员包含两部分,一部分是从基类继承过来的,一类是自己增加的成员,从基类继承过来的表现为共性,子类中新增的成员体现了其个性。
通过公共继承(public) 方式,成员属性或方法在父类中是什么样的访问方式,在子类中还是怎样的访问方式;通过保护继承(protected) 方式,成员属性或方法在父类中是公共或保护访问方式的,在子类中以保护方式访问;通过私有继承(private)方式,成员属性或方法在父类中是公共或保护访问方式的,在子类中以私有方式访问;父类中私有的成员属性或方法在子类中不能被访问。保护权限下的成员属性或方法在子类内可以访问,子类外不可以访问。
在这里插入图片描述
如果再对子类做继承,同样要看继承方式,子类中私有的属性或方法经继承后全都访问不了。
值得一提的是,父类中的私有成员只是被隐藏了,但是仍然会继承下去。
网页中一般都是这样设计的,有公共的头部和底部信息,点开不同的链接之后,这些公有的信息没有变化,但是却有自己独有的部分,这就用到了继承。
如果不使用继承,对上面提到的网页例子以普通的方式来实现,代码如下所示。

#include <iostream>
#include <string>
using namespace std;

class Java
{
public:
	void head()
	{
		cout<<"公共头部信息..."<<endl;
	}
	void foot()
	{
		cout<<"公共底部信息..."<<endl;
	}
	void content()
	{
		cout<<"Java学习视频..."<<endl;
	}
};

class Python
{
public:
	void head()
	{
		cout<<"公共头部信息..."<<endl;
	}
	void foot()
	{
		cout<<"公共底部信息..."<<endl;
	}
	void content()
	{
		cout<<"Python学习视频..."<<endl;
	}
};

class CPP
{
public:
	void head()
	{
		cout<<"公共头部信息..."<<endl;
	}
	void foot()
	{
		cout<<"公共底部信息..."<<endl;
	}
	void content()
	{
		cout<<"C++学习视频..."<<endl;
	}
};

void fun() 
{
	Java ja;
	ja.head();
	ja.content();
	ja.foot();
	cout<<"----------------"<<endl;
	Python py;
	py.head();
	py.content();
	py.foot();
	cout<<"----------------"<<endl;
	CPP c;
	c.head();
	c.content();
	c.foot();
}

int main()
{
	fun();

	system("pause");
	return 0;
}

可以看到,不同的类中用到了许多重复的代码,如果采用继承的方式,优化后的代码如下。

#include <iostream>
#include <string>
using namespace std;

class BasePage
{
public:
	void head()
	{
		cout<<"公共头部信息..."<<endl;
	}
	void foot()
	{
		cout<<"公共底部信息..."<<endl;
	}
};

//继承基类,一定要加继承方式public,不写默认是private,无法访问
class Java : public BasePage
{
public:
	void content()
	{
		cout<<"Java学习视频..."<<endl;
	}
};

class Python : public BasePage
{
public:
	void content()
	{
		cout<<"Python学习视频..."<<endl;
	}
};

class CPP : public BasePage
{
public:
	void content()
	{
		cout<<"C++学习视频..."<<endl;
	}
};

void fun() 
{
	Java ja;
	ja.head();
	ja.content();
	ja.foot();
	cout<<"----------------"<<endl;
	Python py;
	py.head();
	py.content();
	py.foot();
	cout<<"----------------"<<endl;
	CPP c;
	c.head();
	c.content();
	c.foot();
}

int main()
{
	fun();

	system("pause");
	return 0;
}

上面的两个代码运行结果是一样的,如下图所示,但是通过继承方式写出来的代码减少了很多的重复,这种重复在多继承的情况的尤为明显。
在这里插入图片描述

2.继承中的对象模型

父类中所有的非静态成员属性都会被子类继承下去,父类中的私有成员属性被编译器隐藏了,但是仍然会被继承。
下面代码很好的说明了父类中的哪些属性被子类继承了。
在这里插入图片描述

3.继承中构造函数和析构函数的顺序

先执行父类的构造函数,再执行子类的构造函数;析构函数的执行顺序是先执行子类的析构函数,再执行父类的析构函数。
测试构造函数和析构函数的顺序的代码如下。

#include <iostream>
#include <string>
using namespace std;

class Parent
{
public:
	Parent()
	{
		cout<<"Parent构造函数!"<<endl;
	}
	~Parent()
	{
		cout<<"Parent析构函数!"<<endl;
	}
};

class Son : public Parent
{
public:
	Son()
	{
		cout<<"Son构造函数!"<<endl;
	}
	~Son()
	{
		cout<<"Son析构函数!"<<endl;
	}
};

void fun()
{
	Son s;
}

int main()
{
	fun();

	system("pause");
	return 0;
}

上面代码的执行结果如下图所示。
在这里插入图片描述

4.继承中同名成员的处理方式

如果子类有和父类同名的成员,访问子类成员的时候,直接访问即可,访问父类成员则要加父类名限定作用域。
如果子类有和父类同名的成员函数,子类的同名成员会隐藏掉父类中的所有同名成员函数,包括重载的函数。如果要访问到父类中被隐藏的同名成员函数,需要加作用域。
继承中同名成员属性或成员方法的使用和调用如下图所示。

#include <iostream>
#include <string>
using namespace std;

class Parent
{
public:
	Parent()
	{
		a = 10;
	}
	void fun()
	{
		cout<<"Parent类中的fun()函数调用!"<<endl;
	}
	void fun(int b)
	{
		cout<<"Parent类中的fun(int b)函数调用!"<<endl;
	}
	int a;
};

class Son : public Parent
{
public:
	Son()
	{
		a = 20;
	}
	void fun()
	{
		cout<<"Son类中的fun()函数调用!"<<endl;
	}
	int a;
};

void fun()
{
	Son s;
	cout<<"s.a = "<<s.a<<endl;
	cout<<"s.Parent::a = "<<s.Parent::a<<endl;
	s.fun();
	s.Parent::fun();
	s.Parent::fun(1);
}

int main()
{
	fun();

	system("pause");
	return 0;
}

上面代码的执行结果如下图所示。
在这里插入图片描述

5.继承中同名静态成员处理方式

同名静态成员的处理方式和非静态处理方式一样,不过静态成员的访问方式既可以通过对象实现,也可以通过类名实现。
通过类名访问实现时需要注意两个::的区别,前一个::是以类名的方式访问成员,后一个::则是区分同名成员的作用域。
继承中同名静态成员处理方式的代码如下。

#include <iostream>
#include <string>
using namespace std;

class Parent
{
public:
	static void fun()
	{
		cout<<"Parent类中的fun()函数调用!"<<endl;
	}
	static void fun(int b)
	{
		cout<<"Parent类中的fun(int b)函数调用!"<<endl;
	}
	static int a;  //类内声明
};

class Son : public Parent
{
public:
	static void fun()
	{
		cout<<"Son类中的fun()函数调用!"<<endl;
	}
	static int a;
};

int Parent::a = 10;   //类外初始化
int Son::a = 20; 

void fun()
{
	Son s;
	cout<<"通过实例化的对象访问静态成员:"<<endl;
	cout<<"s.a = "<<s.a<<endl;
	cout<<"s.Parent::a = "<<s.Parent::a<<endl;
	s.fun();
	s.Parent::fun();
	s.Parent::fun(1);
	cout<<"通过类访问静态成员:"<<endl;
	cout<<"Son::a = "<<Son::a<<endl;
	//cout<<"Parent::a = "<<Parent::a<<endl;    //通过父类直接访问的,不是以子类访问的
	cout<<"Parent::a = "<<Son::Parent::a<<endl;  
	//第一个::是以类名的方式访问静态成员;第二个::是以限定同名成员变量的作用域
	Son::fun();
	Son::Parent::fun();
	Son::Parent::fun(1);
}

int main()
{
	fun();

	system("pause");
	return 0;
}

上面代码的执行结果如下图所示。
在这里插入图片描述

6.继承多个父类

C++中允许一个类继承多个类,多继承可能会出现同名成员,需要加作用域进行区分。
多继承语法:class 子类名 :继承方式 父类名1,继承方式 父类名2,…
多继承的代码示例如下所示。

#include <iostream>
#include <string>
using namespace std;

class Base1
{
public:
	Base1()
	{
		a = 10;
	}
	int a;
};

class Base2
{
public:
	Base2()
	{
		a = 20;
	}
	int a;
};

class Son : public Base1, public Base2
{
public:
	Son()
	{
		a = 30;
	}
	int a;
};

void fun()
{
	Son s;
	cout<<"s.a = "<<s.a<<endl;
	cout<<"s.Base1::a = "<<s.Base1::a<<endl;
	cout<<"s.Base2::a = "<<s.Base2::a<<endl;
}

int main()
{
	fun();

	system("pause");
	return 0;
}

上面代码的执行结果如下图所示。
在这里插入图片描述
如果不加作用域,默认访问的是本类的成员变量,如果要访问不同类中的同名成员变量,需要加上作用域才能实现访问。

7.菱形继承

菱形继承:两个子类(派生类)继承了同一个父类(基类),同时又有某个类继承了两个子类,菱形继承也称钻石继承。
在这里插入图片描述
菱形继承的一个典型例子如下图所示。
在这里插入图片描述
菱形继承中,子类继承父类的时候会将属性在各自的类中继承一份,因此,再有类继承子类就会得到两个相同的属性,所以菱形继承中一定存在着同名成员,导致资源浪费且有出现歧义。要利用虚继承解决同名成员的问题,在继承方式前面加上关键字virtual就代表虚继承。
虚继承继承的不再是成员的属性,而是一个虚基类指针,这两个指针在子类中通过不同的偏移量最终指向父类中的成员属性,如下图所示。
在这里插入图片描述
菱形继承的代码示例如下。

#include <iostream>
#include <string>
using namespace std;
//基类
class Animal
{
public:
	int age;
};
//派生类
class Sheep : virtual public Animal{};
class Tuo : virtual public Animal{};
//继承两个派生类
class SheepTuo : public Sheep, public Tuo{};

void fun()
{
	SheepTuo st;
	st.age = 18;
	cout<<"st.age = "<<st.age<<endl;
	cout<<"st.Sheep::age = "<<st.Sheep::age<<endl;
	cout<<"st.Tuo::age = "<<st.Tuo::age<<endl;
	cout<<"st.Animal::age = "<<st.Tuo::age<<endl;
	cout<<"sizeof(st) = "<<sizeof(st)<<endl;
}

int main()
{
	fun();

	system("pause");
	return 0;
}

上面代码的执行结果如下图所示。
在这里插入图片描述
可以看到,通过虚继承,访问成员属性的时候直接通过.访问即可, 不用再加类名作为作用域,因为继承下来的数据只有一份,不会产生歧义。
最终类的大小是12个字节,其中有4个字节是继承自父类的成员属性,另外8个字节分别是来自两个派生类的虚基类指针。
若不采用虚继承的方式,上面类的大小是8个字节,父类中的成员属性被两个派生类继承了,再由一个类继承了两个派生类的属性,因此就是8字节大小。
在这里插入图片描述


本文参考视频:
黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity中URP下实现能量罩(交接处高亮)

文章目录 前言一、交接处高亮 原理1、 我们先用一个球作为能量罩、一个Cube 和 一个 椭球 作为与能量罩交接的物体2、 这是我们目前场景的深度图3、使能量罩为 半透明渲染队列 且 关闭深度写入 不渲染深度图 二、交接处高亮 实现1、得到深度图2、在片元着色器中&#xff0c;对深…

重新认识Elasticsearch-一体化矢量搜索引擎

前言 2023 哪个网络词最热&#xff1f;我投“生成式人工智能”一票。过去一年大家都在拥抱大模型&#xff0c;所有的行业都在做自己的大模型。就像冬日里不来件美拉德色系的服饰就会跟不上时代一样。这不前段时间接入JES&#xff0c;用上好久为碰的RestHighLevelClient包。心血…

静态网页设计实践(HTML+CSS)

一、前端程序员必会三大编程语言 &#xff08;一&#xff09;HTML&#xff08;.html/.htm&#xff09; 超文本标记语言&#xff08;HyperText Markup Language&#xff0c;简称:HTML&#xff09;是一种用于创建网页的标准标记语言。HTML是一种基础技术&#xff0c;常与CSS、Ja…

YOLOv8改进 | 二次创新篇 | 结合iRMB和EMA形成全新的iEMA机制(全网独家创新)

一、本文介绍 本文给大家带来的改进机制是二次创新的机制,二次创新是我们发表论文中关键的一环,为什么这么说,从去年的三月份开始对于图像领域的论文发表其实是变难的了,在那之前大家可能搭搭积木的情况下就可以简单的发表一篇论文,但是从去年开始单纯的搭积木其实发表论…

JWT的初级认识

文章目录 一.什么是JWT二.JWT能够做什么1.授权2.信息交换 三.为什么我们使用JWT传统的基于session的认证流程基于JWT认证1.认证流程2.jwt优势 四.JWT的结构是什么Header的组成4.2 Header4.3 Payload4.4 Signature签名目的 五.使用JWT5.1 引入JWT依赖5.2 生成token5.3 根据令牌和…

vue element-ui的table列表中展示缩略图片效果实例

这篇文章主要给大家介绍了关于vue element-ui的table列表中展示多张图片(可放大)效果的相关资料,文中通过代码示例介绍的非常详细,需要的朋友可以参考下 一、效果图 二、代码部分 1、原理 使用 <el-table-column> 和 <el-image> 组件来在表格中插入缩略图 2、te…

回归预测 | Matlab基于SO-LSTM蛇群算法优化长短期记忆神经网络的数据多输入单输出回归预测

回归预测 | Matlab基于SO-LSTM蛇群算法优化长短期记忆神经网络的数据多输入单输出回归预测 目录 回归预测 | Matlab基于SO-LSTM蛇群算法优化长短期记忆神经网络的数据多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于SO-LSTM蛇群算法优化…

py的循环语句(for和while)

前言&#xff1a;本章节和友友们探讨一下py的循环语句&#xff0c;主播觉得稍微有点难主要是太浑了&#xff0c;但是会尽量描述清楚&#xff0c;OK上车&#xff01;&#xff08;本章节有节目效果&#xff09; 目录 一.while循环的基本使用 1.1关于while循环 1.2举例 1.31-1…

TensorFlow相关组件的安装

安装Anaconda3 安装Anaconda3的时候可以安装在任意磁盘中&#xff0c;在勾选path的时候全部勾选即可。更换Anaconda3的下载源为清华大学源&#xff0c;在此期间不要打开Anaconda3&#xff0c;在cmd中依次输入以下即可&#xff1a; conda config --add channels https://mirro…

【JaveWeb教程】(17) MySQL数据库开发之 MySQL简介、安装、数据类型、SQL通用语法 详细代码示例讲解

目录 前言1. MySQL概述1.1 安装1.1.1 版本1.1.2 安装1.1.3 连接1.1.4 企业使用方式(了解) 1.2 数据模型1.3 SQL简介1.3.1 SQL通用语法1.3.2 分类 前言 在我们讲解SpringBootWeb基础知识(请求响应案例)的时候&#xff0c;我们讲到在web开发中&#xff0c;为了应用程序职责单一&…

搜索与图论第一期 DFS(深度优先搜索)

前言 DFS这部分难度不大&#xff0c;大家应该完全掌握&#xff01;&#xff01;&#xff01; 一、DFS的基本内容 内容&#xff1a; 深度优先遍历图的方法是&#xff0c;从图中某顶点v出发&#xff1a; &#xff08;1&#xff09;访问顶点v&#xff1b; &#xff08;2&#…

Element Plus 离线手册 下载

Element Plus (Vue3) 离线手册&#xff0c;解压就能用&#xff0c;双击运行&#xff0c;浏览器访问 http://localhost:7011 获取方式&#xff1a;原文关注微信公众号&#xff0c;回复消息&#xff1a;7011ELP Element Plus 离线手册 下载Vue3 Element Plus 离线手册 离线文档 …

【教学类-45-05】X-Y之间的三连加减题混合 (横向排列)(44格:11题“++ ”11题“--”11题“ +-”11题“ -+” )

作品展示&#xff1a; 背景需求&#xff1a; 把以下四款3连题 混在一起&#xff0c;每种题目随机抽取11题&#xff0c;一共44格 【教学类-45-02】X-Y之间的“三连减“题(a-b-c)-CSDN博客文章浏览阅读465次&#xff0c;点赞15次&#xff0c;收藏7次。【教学类-45-02】X-Y之间的…

【算法】最佳牛围栏(二分,前缀和,双指针)

题目 农夫约翰的农场由 N 块田地组成&#xff0c;每块地里都有一定数量的牛&#xff0c;其数量不会少于 1 头&#xff0c;也不会超过 2000 头。 约翰希望用围栏将一部分连续的田地围起来&#xff0c;并使得围起来的区域内每块地包含的牛的数量的平均值达到最大。 围起区域内…

Apache ActiveMQ RCE CNVD-2023-69477 CVE-2023-46604

漏洞简介 Apache ActiveMQ官方发布新版本&#xff0c;修复了一个远程代码执行漏洞&#xff0c;攻击者可构造恶意请求通过Apache ActiveMQ的61616端口发送恶意数据导致远程代码执行&#xff0c;从而完全控制Apache ActiveMQ服务器。 影响版本 Apache ActiveMQ 5.18.0 before …

java基础之Java8新特性-Optional

目录 1.简介 2.Optional类常用方法 3.示例代码 4.示例代码仓库地址 1.简介 Java 8引入了一个重要的新特性&#xff0c;即Optional类。Optional类是为了解决空指针异常而设计的。 在Java中&#xff0c;当我们尝试访问一个空对象的属性或调用其方法时&#xff0c;很容易抛出…

【sklearn练习】模型评估

一、交叉验证 cross_val_score 的使用 1、不用交叉验证的情况&#xff1a; from __future__ import print_function from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifieriris…

centos7下升级nginx1.8.0版本到nginx1.25.3版本

1、指定目录下载安装包 wget http://nginx.org/download/nginx-1.25.3.tar.gz 2、重命名老版本nginx目录 cd /usr/local/ mv nginx nginx_1.8.0 3、解压更新版本的压缩包 tar -zxvf nginx-1.25.3.tar.gz 4、进入nginx安装包目录下执行如下命令检测系统环境 --with-stream: 添…

Citrix思杰虚拟桌面离场,国产云桌面是否应继续对接微软Windows AD域?

2023年&#xff0c;12月3日&#xff0c;Citrix&#xff08;思杰&#xff09;全面退出中国市场。Citrix进入中国市场时&#xff0c;定位是大客户、高价值企业&#xff0c;客户群集中在国企、大型制造业、外资、金融等中大型企业&#xff0c;例如华为、中国移动、平安银行、建设银…

【Python】编程练习的解密与实战(二)

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《Python | 编程解码》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 ​ 目录 &#x1fa90;1. 初识Python …