C++期末复习总结(2)

目录

1.运算符重载

2.四种运算符重载

(1)关系运算符的重载

(2) 左移运算符的重载

(3)下标运算符的重载

 (4)赋值运算符的重载

3.继承的方式

4.继承的对象模型

5.基类的构造

6.名字遮蔽和类作用域

7.类继承的特殊关系

8.多态和虚函数


1.运算符重载

(1)其实这个知识我们并不是很陌生,我们在C语言学习阶段,就知道了*这个运算符,在我们学习基本的运算的时候,这个运算符就是用来计算乘法的,但是后来我们学到了指针之后,这个运算符就用来表示对于一个指针变量的解引用,这个时候我们就已经认识到了一个运算符的重载功能;

(2)我们通过下面这个实际的场景认识一下什么是c++里面的运算符重载,我们下面的这个代码场景是要为这个超女的分数上面加上30分,这个时候如果我们直接拿这个对象和数字相加,编译器是肯定不会通过的,因为这个编译器不知道要把这个数据加到那个成员变量上面去;

(3)针对这个问题,我们有两种解决方案,第一种就是设置一个函数,实现这个加分的功能,指定这个分数加到那个成员变量上面去,我们原本初始化这个分数是90,加上30分之后这个分数就变成了120分;

#include<string>
using namespace std;
class cgril
{
	friend void addscore(cgril& g, int score);
private:
	int m_xw;//超女的行为
	int m_score;//超女的分数
public:
	string m_name;//超女的姓名
	cgril()
	{
		m_xw = 60;
		m_name = "张三";
		m_score = 90;
	}
	void show()
	{
		cout << "行为:" << m_xw << "分数:" << m_score << "姓名:" << m_name << endl;
	}
};
void addscore(cgril& g, int score)//利用函数,实现加分的功能
{
	g.m_score = g.m_score + score;
}
int main()
{
	//导演的要求就是,每轮表演之后,加上对应的得分
	cgril g;
	addscore(g, 30);
	g.show();
	return 0;
}

(4)上面的这个写法偏向于C的写法,接下来我们看一下如何使用C++写法实现这个加分的功能,就是把这个函数的名字修改为operator+即可,这个operator是关键字,+就是我们想要重载的运算符 ;

(5)上面的这个运算符重载的基本写法,实际上这个运算符的重载既可以写作成员函数,也可以写作全局函数,当我们实现一个类和一个整形数据加法的时候,如果我们写在成员函数里面,就可以只写一个参数,最后的返回值是*this,这个时候写法是这样的;

	cgril& operator+(int score)//利用函数,实现加分的功能
	{
		m_score = m_score + score;
		return *this;
	}
};
int main()
{
	//导演的要求就是,每轮表演之后,加上对应的得分
	cgril g;
	g = g + 30;
	g.show();
	return 0;
}

这个时候,那个对象调用这个成员函数,那个对象就是this指针,这样写在成员函数里面,我们就不需要写这个友元函数了,因为这个在类的里面,我们是可以对于这个私有的成员变量直接进行使用,这个时候g=g+30我们需要把这个返回值设置为这个类的引用类型;

(6)当这个函数写在全局里面时候,有几个操作数,我们就需要写几个操作数,而且这个操作数的数据类型和我们使用的数据类型之间应该是一一对应的,例如我们想要实现这个cgril+int,我们在使用这个加法运算符的时候,我们就必须把这个类写在左边,int类型的数据写在右边,这个顺序是不可以改变的;

(7)下面的这些运算符重载的时候必须写在这个成员函数里面去:赋值运算符=    函数调用运算符( )   下标运算符[  ]      以及这个指针访问成员操作符->   ;

2.四种运算符重载

(1)关系运算符的重载

关系运算符就是我们常说的这个大于小于和等于这些符号的比较,我们对于两个类之间的比较,需要自己进行运算符的重载;

下面的就是重载了等于号大于号和小于号的运算符重载代码;

class student
{
	string m_name;
	int m_cj;//学生成绩
	int m_bx;//学生的表现
	int m_td;//学生的学习态度
public:
	student(string name, int cj, int bx, int td)
	{
		m_name = name;
		m_cj = cj;
		m_bx = bx;
		m_td = td;
	}
	bool operator==(const student& s)
	{
		if (m_cj + m_bx + m_td == s.m_cj + s.m_bx + s.m_td)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	bool operator<(const student& s)
	{
		if (m_cj + m_bx + m_td < s.m_cj + s.m_bx + s.m_td)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	bool operator>(const student& s)
	{
		if (m_cj + m_bx + m_td > s.m_cj + s.m_bx + s.m_td)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
};
int main()
{
	student s1("张三", 80, 20, 70);
	student s2("李四", 70, 70, 30);
	if (s1 == s2)
	{
		cout << "张三和李四的分数一样" << endl;
	}
	else
	{
		if (s1 < s2)
		{
			cout << "张三比李四的分数低" << endl;
		}
		else
		{
			cout << "张三比李四的分数高" << endl;
		}
	}
	return 0;
}

(2) 左移运算符的重载

这个cout有15种重载,因此可以输出各种数据类型的数据,但是cout无法输出我们自己定义的类和对象,这个时候就需要我们对于其进行重载,cout这个对象的返回值实际上就是一个ostream类型的,这个如果是全局函数,就需要两个参数,一个就是cout对象,一个就是我们的自定义类型的对象,如果是成员函数的话,,就只需要一个参数,因为对象本身是隐式传递的,不能出现在形参列表里面;

using namespace std;
class student
{
	friend ostream& operator<<(ostream& cout, const student& s);
	int m_mark;
	string m_name;
public:
	student()
	{
		m_mark = 90;
		m_name = "张三";
	}
	void show()
	{
		cout << "这个同学的姓名是" << m_name << "成绩是:" << m_mark << endl;
	}
};
ostream& operator<<(ostream& cout, const student& s)
{
	cout << "姓名:" << s.m_name << "  分数:" << s.m_mark << endl;
	return cout;
}
int main()
{
	student s1;
	cout << s1 << endl;
	return 0;
}

成员函数版本的运算符重载:

#include<string>
using namespace std;
class student
{
	//friend ostream& operator<<(ostream& cout, const student& s);
	int m_mark;
	string m_name;
public:
	student()
	{
		m_mark = 90;
		m_name = "张三";
	}
	void show()
	{
		cout << "这个同学的姓名是" << m_name << "成绩是:" << m_mark << endl;
	}
	ostream& operator<<(ostream& cout)
	{
		cout << "姓名:" << this->m_name << "  分数:" << this->m_mark << endl;
		return cout;
	}
};
int main()
{
	student s1;
	s1 << cout << endl;
	return 0;
}

 我们可以理解为这个运算符左右两边一共有两个操作数,这个时候我们的自定义类型作为一个隐藏的参数,所以对应的主函数里面这个自定义对象和cout对象的位置需要被改变;

这个时候cout在右边,不是我们想要的结果,因此这个左移运算符的重载,只能写成这个全局函数,不能写成成员函数;

(3)下标运算符的重载

如果没有重载下标运算符,如果我们想要查看这个数组元素,我们就需要自己定义函数,使用这个小括号加上下标的方式表示,但是我们知道这个访问操作符就是中括号,因此下面我们介绍小标访问运算符的重载;

#include<iostream>
#include<string>
using namespace std;
class student
{
private:
	string m_zy[3];
public:
	student()
	{
		m_zy[0] = "父母";
		m_zy[1] = "老师";
		m_zy[2] = "朋友";
	}
	void show()
	{
		cout << m_zy[0] << "  " << m_zy[1] << "  " << m_zy[2] << "  " << endl;
	}
	string& operator[](int ii)
	{
		return m_zy[ii];
	}
};
int main()
{
	student s1;
	s1[2] = "知己";
	cout << "第三亲密:" << s1[2] << endl;
	s1.show();
	return 0;
}

实际在开发的过程中,我们需要有两个版本的重载函数,一个版本是可以对于我们的数据进行修改的,另外的一个就是针对常变量只能调用常函数;

#include<iostream>
#include<string>
using namespace std;
class student
{
private:
	string m_zy[3];
public:
	student()
	{
		m_zy[0] = "父母";
		m_zy[1] = "老师";
		m_zy[2] = "朋友";
	}
	void show()
	{
		cout << m_zy[0] << "  " << m_zy[1] << "  " << m_zy[2] << "  " << endl;
	}
	string& operator[](int ii)
	{
		return m_zy[ii];
	}
	const string& operator[](int ii) const
	{
		return m_zy[ii];
	}
};
int main()
{
	student s1;
	s1[2] = "知己";
	cout << "第三亲密:" << s1[2] << endl;
	s1.show();

	const student s2 = s1;
	cout << "第三亲密:" << s2[2] << endl;
	return 0;
}

 (4)赋值运算符的重载

赋值运算符其实编译器会提供默认的,我们了解即可,这个我们在重载赋值运算符的时候,需要判断这个时不时会出现自己给自己赋值的情况,这个是合法的,我们直接返回this解引用即可;this就是我们想要赋值的对象;

编译器默认提供的赋值构造函数是浅拷贝,如果这个不存在动态开辟空间,就可以满足需求,否则的话就需要我们自己实现深拷贝;

#include<iostream>
#include<string>
using namespace std;
class student
{
public:
	string m_name;
	int m_score;
	void show()
	{
		cout << "姓名:" << m_name << "    年龄:" << m_score << endl;
	}
	student& operator=(const student& s)
	{
		if (this == &s)
			return *this;
		else
		{
			m_name = s.m_name;
			m_score = s.m_score;
		}
		return *this;
	}
};
int main()
{
	student s1;
	s1.m_name = "张三";
	s1.m_score = 100;
	s1.show();
	student s2;
	s2 = s1;
	s2.show();
	return 0;
}

3.继承的方式

(1)三种不同的继承方式

上面展示的就是三种不同的继承方式,我们假设这个基类有三个成员变量,一个是共有的,一个是受保护的,一个是私有的,经过不同的继承方式之后,这个成员变量的类型会发生什么变化;

第一种就是公有继承,公有继承的时候,我们的父类里面的公有成员还是公有成员,受保护的成员还是受保护的成员,私有成员就不存在了;

第二种是受保护的继承,这个时候,原来的公有成员就变成了受保护的成员,原来的父类里面的受保护的成员还是受保护的,原来的私有成员变量这个时候还是不存在的;

第三种就是私有的继承,这个时候,原来的父类里面的共有的成员变量和保护的成员变量就是私有的了,原来的父类里面的受保护的成员变量也是不存在的;

(2)我们在这个继承的子类里面是没有办法访问这个所谓的父类里面的私有成员变量的,但是如果我们想要在这个子类里面去访问这个私有的成员变量,可以在父类里面添加共有的函数访问这个私有的成员变量,这个时候我们就可以直接调用这个函数访问父类里面的私有的成员变量;

就像下面的展示那样,我们在子类里面本来是没有办法去访问父类的私有成员变量的,但是我们可以在父类里面创建共有的成员函数,这样在子类里面,我们就可以通过调用这个函数达到间接访问了父类的私有成员变量的目的;

class comers
{
private:
	int m_aa;
public:
	void func()
	{
		cout << m_aa << endl;
	}
};
class comerss :public comers
{
private:
	int m_bb;
public:
	void show()
	{
		func();
	}
};
int main()
{
	comerss c1;
	c1.show();
	return 0;
}

(3)我们可以使用using 关键字改变父类的成员变量的访问权限,例如我们可以把这个共有的改变成为受保护的,把这个受保护的改变权限为共有的,这个父类里面的私有的成员变量的权限是没有办法通过这个关键字改变的,因为这个父类里面的私有的成员变量在这个子类里面根本就不会存在,因此这个关键字只对于public权限和protected权限发挥作用;

class a
{
public:
	int m_a;
protected:
	int m_b;
private:
	int m_c;
};
class b :public a
{
public:
	using a::m_b;
protected:
	using a::m_a;
};
int main()
{	
	b bb1;
	return 0;
}

通过上面的这个具体的实例,我们就可以把这个父类里面的公有成员变量修改为受保护的,把这个受保护的成员变量修改权限为公有的,当然也可以把他们的权限设置为私有的;

4.继承的对象模型

(1)这个地方是帮助我们了解C++继承语法的底层逻辑,而不是学懂这个底层逻辑,我们只是了解,这样就可以让我们更好理解前面的一些原因;

(2)第一点就是基类在写这个构造函数的时候,会先运行这个父类的构造函数,再去运行这个基类的构造函数,这个我们可以进行尝试,当我们创建两个类,假设是A类和B类,如果A是父类,B是子类,我们把这个A类里面的构造函数设置为私有的,这个时候我们在B这个子类里面去写构造函数就会报错,原因就是我们上面提及到的我们在执行子类的构造函数的时候,会先执行父类的构造函数,这个也是为什么我们建议把这个函数写为共有的,成员变量写为私有的,这个时候我们学习了继承,就可以更好地进行理解;

(3)销毁子类对象的时候,会先执行子类的析构函数,再去执行父类的析构函数,这个和构造函数的执行顺序是恰好相反的;

(4)创建派生类对象的时候,只申请了一次这个内存,申请的内存空间的大小就是基类加上派生类的内存的和,先调用基类的构造函数,初始化基类,再调用派生类的构造函数,初始化派生类,在基类和派生类的构造函数里面,this指针是相同的地址,派生类和基类都有的成员变量的地址也是一样的;

(5)在C++里面这个成员变量的访问权限只是语法上面的限制,我们可以使用memset函数清零数据,包括这个私有的成员变量,即使这个私有的成员变量在类的外面不能被访问;我们可以使用指针突破这个访问权限的限制,所以这个访问权限只是语法上面的一个解释罢了;

5.基类的构造

(1)我们可以使用初始化列表的方式指定要使用的基类的构造函数类型,因为我们前面提及过,这个创建子类也就是派生类的对象的时候,需要先去调用这个父类的构造函数,这个时候如果父类里面有多个构造函数,我们就可以使用初始化列表的方式指定调用基类里面的哪个构造函数;

(2)我们在创建派生类的对象的时候,是使用基类初始化这个基类的成员变量,派生类初始化派生类的成员变量,你可能会问,这些基类的成员变量都被派生类给继承了,为什么不使用派生类初始化基类的成员变量,这个有两点原因;

第一就是我们的基类里面的私有的成员变量我们是无法在这个派生类里面看到的,更别说去对于这个变量进行初始化了;

第二就是这个如果我们在这个派生类里面对于这个基类的成员变量进行初始化,如果这个基类有很多个派生类,我们的这个代码就显得很冗余,而且这个派生类存在的意义就是减少这个相同的成员变量的书写带来的麻烦,这样搞得话就不符合这个逻辑了;

(3)下面的就是我们定义了一个派生类和一个基类,通过初始化列表的方式,确定这个派生类调用的是基类里面的哪个构造函数;

class a
{
public:
	int m_a;
private:
	int m_b;
public:
	a()
		:m_a(0)
		, m_b(0)
	{
		cout << "调用了基类的构造函数" << endl;
	}
	a(int aa, int bb)
		:m_a(aa)
		, m_b(bb)
	{
		cout << "调用了含有两个参数的构造函数" << endl;
	}
	a(const a& aa)
		:m_a(aa.m_a + 1)
		, m_b(aa.m_b + 1)
	{
		cout << "调用了基类的拷贝构造函数" << endl;
	}
	void showa()
	{
		cout << "m_a数值大小:" << m_a << "m_b的数值大小" << m_b << endl;
	}
};
class b :public a
{
public:
	int m_c;
	b()
		:m_c(0)
		,a()
	{
		cout << "调用了这个派生类的构造函数" << endl;
	}
	b(int a, int b, int c)
		:a(a, b)
		, m_c(c)
	{
		cout << "调用派生类的构造函数b(int a, int b, int c)" << endl;
	}
	b(const a& aa, int c)
		:a(aa)
		, m_c(c)
	{
		cout << "调用派生类的拷贝构造函数" << endl;
	}
	void showb()
	{
		cout << "m_c数值大小:" << m_c << endl;
	}
};
int main()
{
	b b1;
	b1.showa();
	b1.showb();
	cout << endl;

	b b2(1, 2, 3);
	b2.showa();
	b2.showb();
	cout << endl;

	a a1(10, 20);
	b b11(a1, 30);
	return 0;
}

我们分别使用初始化列表的方式指定了调用默认的构造函数,调用含有多个参数的构造函数,以及这个拷贝构造函数;子类里面的第二个初始化列表我们使用的是这个基类的含有两个参数的构造函数进行初始化的,第三个初始化列表是使用基类里面的拷贝构造函数进行初始化的;

6.名字遮蔽和类作用域

(1)下面就是定义了一个基类和一个子类,我们创建了一个子类的对象,这个基类和子类的这个成员变量的名字以及这个成员函数的名字都是一样的,这个时候我们的打印结果就是基类的成员变量和成员函数;

using namespace std;
class a
{
public:
	int m_a = 20;
	void show()
	{
		cout << "调用了基类的函数" << endl;
	}
};
class b :public a
{
public:
	int m_a = 30;
	void show()
	{
		cout << "调用了派生类的函数" << endl;
	}
};
int main()
{
	b b1;
	cout << "b1对象的m_a的值是:" << b1.m_a << endl;
	b1.show();
	return 0;
}

(2)当基类的函数名和这个派生类里面的函数名字相同的时候,因为这个是继承,所以派生类里面就会隐含的包括了这个基类的成员变量和成员函数,名字相同的时候,派生类的函数就会把这个基类里面函数覆盖掉;

using namespace std;
class a
{
public:
	int m_a = 20;
	void show()
	{
		cout << "调用了基类的函数" << endl;
	}
	void func(int a)
	{
		cout << "调用了这个函数" << endl;
	}
};
class b :public a
{
public:
	int m_a = 30;
	//void func() { cout << "调用了派生类的函数" << endl; }
};
int main()
{
	b b1;
	cout << "b1对象的m_a的值是:" << b1.m_a << endl;
	b1.show();
	b1.func(1);
}

例如上面的这个程序,两个相同的函数func,如果我们把这个继承类里面的func函数放开,这个时候运行就会报错,因为这个时候父类的func函数会被覆盖掉,我们传递参数是不合语法的,但是我们把这个注释掉之后,就可以运行成功,因为这个时候,不存在函数名字相同的情况,我们就可以直接调用这个子类里面的有一个参数的func函数了,实际上这个成员函数在子类里面也是存在的,只要不重名,这个基类里面的这个函数就不会被覆盖掉;

实际上这个名字遮蔽就是一个表象,类作用域才是实质,因为实际上当存在继承关系的时候,这个基类的作用域是嵌套在这个派生类里面的,我们一般会在这个派生类里面去寻找,只有这个在派生类里面找不到的时候,才回到基类里面去寻找;

7.类继承的特殊关系

(1)如果我们使用派生类的对象赋值给基类的对象(包括私有成员),但是这个时候会舍弃掉非基类成员:

下面这个代码里面,我们对于这个b1对象进行操作,最后把他赋值给a1这个对象,这个时候我们会发现a1这个对象里面的私有成员m_b也会被更新的,也就是说即使是私有的成员变量,也是会被赋值的;

class a
{
public:
	int m_a = 0;
private:
	int m_b = 0;
public:
	void show()
	{
		cout << "m_a:" << m_a << "   m_b:" << m_b << endl;
	}
	void setb(int b)
	{
		m_b = b;
	}
};
class b :public a
{
public:
	int m_c = 0;
	void show()
	{
		cout << "m_a:" << m_a << "   m_c:" << m_c << endl;
	}
};
int main()
{
	a a1;
	b b1;
	b1.m_a = 10;
	b1.setb(20);
	b1.m_c = 30;

	a1.show();
	a1 = b1;
	a1.show();

	return 0;
}

(2)基类的指针可以不经过显示转换指向派生类的对象,因为基类和派生类有特殊的关系,他们的内存模型是一样的,所以使用基类的指针执行派生类,没有问题;

还是上面得继承关系,我们定义基类的指针指向派生类的对象:

int main()
{
	b b1;
	a* a1 = &b1;
	b1.m_a = 10;
	b1.setb(20);
	b1.m_c = 30;
	b1.show();
	a1->m_a = 10;
	a1->setb(20);
	a1->show();
	return 0;
}

8.多态和虚函数

(1)什么是多态?

多态就是我们定义了两个类之间的继承关系,定义了基类的指针pa,指向的是派生类的对象g,这个时候我们使用这个指针去调用函数,就只能调用基类的构造函数,因为这个指针就是基类的;

我们在这个基类的成员函数show前面加上virtual关键字,就可以使用这个执行派生类对象的指针去访问这个派生类的函数,即使这个类是基类的,我们也是可以访问到这个派生类的成员函数的;

因为这个是函数前面加上virtual关键字,我们把这个函数叫做虚函数,有了虚函数之后,基类的指针指向基类对象就会调用基类的成员变量和函数,指向派生类的对象之后就会调用派生类的成员变量和函数,基类的指针表现出来多种形态,我们把这个现象叫做多态;

class allcomer
{
public:
	int m_bh;
	void show()
	{
		cout << "class allcomer我的编号是:" << m_bh << endl;
	}
};
class cgril :public allcomer
{
public:
	int m_age;
	void show()
	{
		cout << "class cgril :public allcomer我的年龄是" << m_age << endl;
	}
};
int main()
{
	cgril g;
	g.m_bh = 8;
	g.m_age = 18;
	g.show();
	allcomer* pa = &g;
	pa->show();
	return 0;
}

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

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

相关文章

中缀表达式和前缀后缀

在中缀表达式中&#xff0c;操作数可能与两个操作符相结合 但是&#xff0c;想要不带括号无歧义&#xff0c;且不需要考虑运算符优先级和结合性 所以考虑 前缀表达式&#xff0c;波兰表达式 后缀表达式 逆波兰表达式 对于人来说&#xff0c;中缀表达式是最容易读懂的。但是对于…

C语言之字符函数总结(全部!),一篇记住所有的字符函数

前言 还在担心关于字符的库函数记不住吗&#xff1f;不用担心&#xff0c;这篇文章将为你全面整理所有的字符函数的用法。不用记忆&#xff0c;一次看完&#xff0c;随查随用。用多了自然就记住了 字符分类函数和字符转换函数 C语言中有一系列的函数是专门做字符分类和字符转换…

无人机、机器人10公里WiFi远距离图传模块,实时高清视频传输,飞睿CV5200模组方案,支持mesh自组网模块

在快速发展的物联网时代&#xff0c;远距离无线通信技术已成为连接各种智能设备的关键。无人机、安防监控、机器人等领域对数据传输的距离和速度要求越来越高。 公里级远距离WiFi模组方案可以通过多种技术和策略的结合来实现无人机和机器人之间的高效通信传输。 飞睿智能CV52…

【Java毕业设计】基于JavaWeb企业违规信息综合管理系统

文章目录 摘 要ABSTRACT目 录1 概述1.1 研究背景及意义1.2 国内外研究现状1.3 拟研究内容1.4 系统开发技术1.4.1 Java编程语言1.4.2 SpringBoot框架1.4.3 MySQL数据库1.4.4 B/S结构1.4.5 MVC模式 2 系统需求分析2.1 可行性分析2.2 功能需求分析 3 系统设计3.1 功能模块设计3.2 …

Python应用开发——30天学习Streamlit Python包进行APP的构建(5)

上几次我们已经将一些必备的内容进行了快速的梳理,让我们掌握了streanlit的凯快速上手,接下来我们将其它的一些基础函数再做简单的梳理,以顺便回顾我们未来可能用到的更丰富的函数来实现应用的制作。 st.write_stream 将生成器、迭代器或类似流的序列串流到应用程序中。 …

数据总线、位扩展、字长

数据总线&#xff08;Data Bus&#xff09; 定义 数据总线是计算机系统中的一组并行信号线&#xff0c;用于在计算机内部传输数据。这些数据可以在中央处理器&#xff08;CPU&#xff09;、内存和输入/输出设备之间传输。 作用 数据传输&#xff1a;数据总线负责在计算机各…

Elasticsearch 认证模拟题 - 15

一、题目 原索引 task1 的字段 title 字段包含单词 The&#xff0c;查询 the 可以查出 1200 篇文档。重建 task1 索引为 task1_new&#xff0c;重建后的索引&#xff0c; title 字段查询 the 单词&#xff0c;不能匹配到任何文档。 PUT task1 {"mappings": {"…

Jar包部署为linux系统服务

文章目录 引言I 以系统服务的方式部署(推荐)1.1 创建systemd服务1.2 SSH上传jar包,并重启服务1.3 收集自定义systemd服务的日志【可选】II 脚本部署方式(不推荐)2.1 启动脚本2.2 关闭脚本2.3 SSH上传jar包,并重启服务III 打包3.1 build中的plugins中标签的含义3.2 jar中没…

代码随想录算法训练营第36期DAY50

DAY50 如果写累了就去写套磁信吧。 198打家劫舍 class Solution {public: int rob(vector<int>& nums) { vector<int> dp(nums.size()); dp[0]nums[0]; if(nums.size()1) return nums[0]; dp[1]max(nums[0],nums[1]); …

【Unity UGUI】Screen.safeArea获取异形屏数据失败

Screen.safeArea获取不到异形屏的尺寸位置等数据 检查AndroidManifest.xml文件是否有设置&#xff1a;android:theme"style/UnityThemeSelector"&#xff0c;没有加上即可 android:theme"style/UnityThemeSelector"

基于大模型 Gemma-7B 和 llama_index,轻松实现 NL2SQL

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学. 针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 汇总合集&…

时光正好保剑锋的抱治百病与成年人的世界

《时光正好》&#xff1a;保剑锋的“抱治百病”与成年人的世界在繁忙的都市里&#xff0c;每个角落上演着各自的人生戏码。而在这些戏码中&#xff0c;由保剑锋主演的《时光正好》无疑成为了近期引人注目的焦点。这部电视剧以其真实而深刻的剧情&#xff0c;让我们看到了成年人…

用于认知负荷评估的集成时空深度聚类(ISTDC)

Integrated Spatio-Temporal Deep Clustering (ISTDC) for cognitive workload assessment 摘要&#xff1a; 本文提出了一种新型的集成时空深度聚类&#xff08;ISTDC&#xff09;模型&#xff0c;用于评估认知负荷。该模型首先利用深度表示学习&#xff08;DRL&#xff09;…

Debug-014-nginx代理路径的一条规则

直接上图&#xff1a; 今天看禹神的前端视频&#xff0c;讲到在nginx中代理路径的时候&#xff0c;有一个规则&#xff1a; 如果/dev和下面的proxy_pass路径最后都带‘/’,那么就是匹配到dev之后要删除dev,然后再带着后面的路径&#xff1b;如果/dev和下面的proxy_pass路径最后…

【上篇】从 YOLOv1 到 YOLOv8 的 YOLO 物体检测模型历史

YOLO 型号之所以闻名遐迩,主要有两个原因:其速度和准确性令人印象深刻,而且能够快速、可靠地检测图像中的物体。 在本文中,我将与大家分享我在阅读一篇长达 30 页的综合性论文时获得的见解,该论文深入探讨了 YOLO 模型的进步。 这篇评论全面概述了 YOLO 框架的演变过程,…

自然语言处理:第三十二章HippoRAG:性能提高20% - 受海马体启发的RAG

文章链接: HippoRAG: Neurobiologically Inspired Long-Term Memory for Large Language Models 项目地址: OSU-NLP-Group/HippoRAG: HippoRAG is a novel RAG framework inspired by human long-term memory that enables LLMs to continuously integrate knowledge across e…

How to: Add and Customize Toolbar Skin Selectors

You can add skin selectors to a toolbar (BarManager) and Ribbon Control to allow users to choose skins at runtime. 将皮肤选择器添加到工具栏 At design time, click the [Add] button in the toolbar, and select a skin selector from the Skin Item sub-menu. 以下…

【C++课程学习】:C++入门(引用)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C课程学习 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 &#x1f369;1.引用的概念&#xff1a; &#x1f369;2.引用和指针是两个概念&#xff1a; &#x…

Python采集东方财富网股票数据建立LSTM模型预测

Python采集东方财富网股票数据建立LSTM模型预测 一、数据爬取流程二、爬虫完整代码三、LSTM模型建模预测3.1 项目背景3.2 建模预测流程3.3 数据预处理3.4 数据可视化3.5 特征工程3.6 数据缩放3.7 数据转换3.8 模型创建3.9 评价模型3.10 可视化结果3.11 总结一、数据爬取流程 先…

LeetCode-165. 比较版本号【双指针 字符串】

LeetCode-165. 比较版本号【双指针 字符串】 题目描述&#xff1a;解题思路一&#xff1a;字符串分割解题思路二&#xff1a;双指针背诵版&#xff1a; 题目描述&#xff1a; 给你两个 版本号字符串 version1 和 version2 &#xff0c;请你比较它们。版本号由被点 ‘.’ 分开的…