C++的类和对象

C++面向对象的三大特性:封装,继承,多态

万事万物皆可为对象,有其相应的属性和行为

一、封装

1.1 封装的意义

 ·将属性和行为作为一个整体,表现生活中的事物

·将属性和行为加以权限控制

·在设计类的时候,属性和行为写在一起,表现事物

1.2 语法

class 类名{        访问权限:属性 / 行为};

eg1.设计一个圆类

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;

//设计一个圆类,求圆的周长:2*PI*半径
const double PI = 3.14;
//class代表一个类,类后面紧跟就是类名称
class Circle {
	//访问权限
public://公共权限
	//属性
	int m_r;//半径

	//行为,通常用函数
	double calculateZC() {
		return 2 * PI * m_r;
	}
};

int main() {
	//通过圆类 创建具体的圆
    //实例化 (通过一个类 创建一个对象的过程)
	Circle cl;
	//给圆对象的属性进行赋值
	cl.m_r = 10;

	cout << "圆的周长:" << cl.calculateZC() << endl;

	system("pause");
	return 0;
}

eg2.设计一个学生类,属性有姓名和学号,可以给姓名和学号赋值,也可以显示

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;

class Student {
	//类中的属性和行为都属于 成员
	//属性  成员属性 成员变量
	//行为  成员函数 成员方法
public:
	//属性
	string m_Name;//姓名
	int m_id;//学号
	//行为
	void showStudent() {
		cout << "姓名:" << m_Name << "学号:" << m_id << endl;
	}
	//给姓名赋值
	void setName(string name) {
		m_Name = name;
	}
	//给学号赋值
	void setId(int id) {
		m_id = id;
	}
};

int main() {
	//实例化
	Student s1;
	//赋值
	s1.m_Name = "张三";
	s1.m_id = 123;
	s1.showStudent();

	Student s2;
	s2.setName("李四");//通过函数赋值
	s2.setId(321);
	s2.showStudent();

	system("pause");
	return 0;
}

1.3 访问权限

类在设计时,可以把属性和行为放在不同的权限下加以控制

1.public        公共权限        成员类内可以访问,类外可以访问

2.protected   保护权限        成员类内可以访问,类外不可以访问,可以继承

3.private        私有权限        成员类内可以访问,类外不可以访问,不可以继承

eg.

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;

class Persson {
public:
	//公共属性
	string m_Name;
protected:
	//保护权限
	string m_Car;
private:
	//私有权限
	int m_Password;

public:
	void func() {
		m_Name = "张三";
		m_Car = "拖拉机";
		m_Password = 123456;//这里类内都可以访问
	}
};

int main() {
	//实例化
	Persson p1;

	p1.m_Name = "李四";
	//p1.m_Car = "奔驰";//保护权限内容,类外无法访问
	//p1.m_Password = 132;//私有权限内容,类外无法访问
	p1.func();
	system("pause");
	return 0;
}

1.4 struct和class区别

在C++中struct和class唯一的区别在于 默认的访问权限不同

·struct默认权限为公共

·class默认权限为私有 

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;

class C1 {
	int m_A;//默认权限  私有
};

struct C2 {
	int m_A;//默认权限   公共
};

int main() {
	//struct 默认权限为公共
	//class 默认权限为私有
	C1 c1;
	//c1.m_A = 100;//会报错的,类外无法访问

	C2 c2;
	c2.m_A = 100;//成功

	system("pause");
	return 0;
}

1.5 成员属性设置为私有

优点1:将所有成员设置为私有,可以自己控制读写权限

优点2:对于写权限,我们可以检测数据的有效性

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;

class Person {
public:
	//姓名的设置
	void setName(string name) {
		m_Name = name;
	}
	string getName() {
		return m_Name;
	}
	void setAge(int age) {
		//检测优点2的,与开始只读不冲突哈
		if (age < 0 || age>100) {
			cout << "年龄"<<age<<"有误" << endl;
			return;
		}
		m_Age = age;

	}
	int getAge() {
		return m_Age;
	}
	void SetIdol(string idol) {
		m_Idol = idol;
	}
private:
	string m_Name;//姓名  可读可写

	int m_Age = 18;//年龄  只读		也可以写在0~100之间

	string m_Idol;//偶像  只写
};


int main() {
	Person p;
	//姓名
	p.setName("张三");
	cout << "姓名:" << p.getName() << endl;
	//年龄
	//p.setAge(20);//报错
	//p.m_Age = 20;//报错
	//后面加的
	p.setAge(15);
	cout << "年龄:" << p.getAge() << endl;
	//偶像
	p.SetIdol("小米");
	//cout << "偶像:" << p.SetIdol() << endl;//报错,只写状态
	system("pause");
	return 0;
}

eg1.设计立方体类,求出其面积和体积,分别用全局函数和成员函数判断两个立方体是否相等

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;

//立方体类的设计
class Cube {
public:
	//设置、获取长,宽,高
	void setL(int L) {
		m_L = L;
	}
	int getL() {
		return m_L;
	}
	void setW(int W) {
		m_W = W;
	}
	int getW() {
		return m_W;
	}
	void setH(int H) {
		m_H = H;
	}
	int getH() {
		return m_H;
	}
	//获取面积
	int calculateS() {
		return 2 * m_L * m_W + 2 * m_L * m_H + 2 * m_H * m_W;
	}
	//获取体积
	int calculateV() {
		return m_L * m_W * m_H;
	}
	//成员函数判断两立方体是否相等
	bool isSameByClass(Cube &c) {
		if (m_L == c.getL() && m_H == c.getH() && m_W == c.getW()) {
			return true;
		}
		else {
			return false;
		}
	}
private:
	int m_L;
	int m_H;
	int m_W;
};

//利用全局函数判断 两个立方体是否相等
bool isSame(Cube& c1, Cube& c2) {
	if (c1.getH() == c2.getH() && c1.getL() == c2.getL() && c1.getW() == c2.getW()) {
		return true;
	}
	return false;
}

int main() {
	Cube c1;
	c1.setH(10);
	c1.setL(10);
	c1.setW(10);

	cout << "c1的面积为:" << c1.calculateS() << endl;
	cout << "c1的体积为:" << c1.calculateV() << endl;

	Cube c2;
	c2.setH(10);
	c2.setL(10);
	c2.setW(10);
	//利用全局函数判断
	bool ret = isSame(c1, c2);
	if (ret) {
		cout << "全局函数判断相等" << endl;
	}
	else {
		cout << "全局函数判断不想等" << endl;
	}
	//利用成员函数判断
	ret = c1.isSameByClass(c2);
	if (ret) {
		cout << "成员函数判断相等" << endl;
	}
	else {
		cout << "成员函数判断不想等" << endl;
	}

	system("pause");
	return 0;
}

eg2.点和圆的关系,设计圆类和点类

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;

class Point {
public:
	void setX(int x) {
		m_X = x;
	}
	int getX() {
		return m_X;
	}
	void setY(int y) {
		m_Y = y;
	}
	int getY() {
		return m_Y;
	}

private:
	int m_X;
	int m_Y;
};


class Circle {
public:
	void setR(int r) {
		m_R = r;
	}
	int getR() {
		return m_R;
	}
	void setCenter(Point center) {
		m_Center = center;
	}
	Point getCenter() {
		return m_Center;
	}

private:
	int m_R;

	//在一个类中可以让另一个类 作为本来中的成员
	Point m_Center;
};
//判断点和圆的关系
void isInCircle(Circle& c, Point& p) {
	//点和圆心的距离
	int distance = (c.getCenter().getX() - p.getX()) * (c.getCenter().getX() - p.getX()) +
		(c.getCenter().getY() - p.getY()) * (c.getCenter().getY() - p.getY());
	//计算半径的平方
	int rDistance = c.getR() * c.getR();

	if (distance == rDistance) {
		cout << "点在圆上" << endl;
	}
	else if (distance > rDistance) {
		cout << "点在圆外" << endl;
	}
	else {
		cout << "点在圆内" << endl;
	}
}

int main() {
	Circle c;
	c.setR(10);
	Point center;
	center.setX(10);
	center.setY(0);
	c.setCenter(center);

	Point p;
	p.setX(10);
	p.setY(11);

	isInCircle(c, p);
	

	system("pause");
	return 0;
}

在这里我们把两个类分开写,写法如下:

文件包括

其中头文件

circle.h

#pragma once
#include <iostream>
#include "point.h"
using namespace std;


class Circle {
public:
	void setR(int r);

	int getR();


	void setCenter(Point center);


	Point getCenter();

private:
	int m_R;

	Point m_Center;
};

point.h

pragma once  //防止头文件重复包含
#include <iostream>
using namespace std;


class Point {
public:
	void setX(int x);

	int getX();

	void setY(int y);

	int getY();

private:
	int m_X;
	int m_Y;
};


circle.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include "circle.h"

void Circle::setR(int r) {
	m_R = r;
}
int Circle::getR() {
	return m_R;
}
void Circle::setCenter(Point center) {
	m_Center = center;
}
Point Circle::getCenter() {
	return m_Center;
}

point.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include "point.h"


void Point::setX(int x) {
	m_X = x;
}
int Point::getX() {
	return m_X;
}
void Point::setY(int y) {
	m_Y = y;
}
int Point::getY() {
	return m_Y;
}

run.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
using namespace std;
#include "circle.h"
#include "point.h"


//判断点和圆的关系
void isInCircle(Circle& c, Point& p) {
	//点和圆心的距离
	int distance = (c.getCenter().getX() - p.getX()) * (c.getCenter().getX() - p.getX()) +
		(c.getCenter().getY() - p.getY()) * (c.getCenter().getY() - p.getY());
	//计算半径的平方
	int rDistance = c.getR() * c.getR();

	if (distance == rDistance) {
		cout << "点在圆上" << endl;
	}
	else if (distance > rDistance) {
		cout << "点在圆外" << endl;
	}
	else {
		cout << "点在圆内" << endl;
	}
}

int main() {
	Circle c;
	c.setR(10);
	Point center;
	center.setX(10);
	center.setY(0);
	c.setCenter(center);

	Point p;
	p.setX(10);
	p.setY(11);

	isInCircle(c, p);
	

	system("pause");
	return 0;
}

头文件只有声明函数,相对应的文件实现函数功能,注意加上类的作用域

二、对象的初始化和清理

2.1 构造函数和析构函数

对象的初始化和清理也是两个非常重要的安全问题

        一个对象或者变量没有初始状态,对其只用后果是未知的,同样的使用完后不清理,也会造成安全问题

        C++利用构造函数析构函数解决上述问题,这两个函数将会被编译器自动调用,完成对象的初始化和清理工作。是强制要我们做的,如果我们不提供构造函数和析构函数,编译器会提供空实现的函数

·构造函数:主要作用于创建对象时为对象的成员赋值,构造函数由编译器自动调用

·析构函数:主要作用于在对象销毁前系统自动调用,执行一些清理功能

构造函数语法:类名(){}

1.构造函数,没有返回值也不写void

2.函数名称与类名相同

3.构造函数可以有参数,因此可以发生重载

4.程序在调用对象时候会自动调用一次构造函数

析构函数语法:~类名(){}

1.析构函数,没有返回值也不写void

2.函数名称与类名相同,在名称前加~

3.构造函数不可以有参数,因此不可以发生重载

4..程序在销毁对象前会自动调用一次析构函数

eg.

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;

class Person {
public:
	//构造函数,可以有参数
	Person() {
		cout << "Person 构造函数的调用" << endl;
	}
	//析构函数
	~Person() {
		cout << "Person 析构函数的调用" << endl;
	}

};


void test01() {
	Person p;//创建在栈上,test01执行完毕后,会释放这个对象
}


int main() {
	test01();
	Person q;//这里只有创建,没有释放

	system("pause");//在这里按下时才会释放q

	return 0;
}

2.2 构造函数的分类及调用

两种分类方式:

        按参数分为:有参构造和无参构造        无参又称为默认构造函数

        按类型分为:普通构造和拷贝构造

三中调用方式:

        括号法、显示法、隐式转换法

eg.

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;

class Person {
public:
	//无参构造(普通构造)
	Person() {
		cout << "Person 的无参构造函数的调用" << endl;
	}
	//有参构造(普通构造)
	Person(int a) {
		age = a;
		cout << "Person 的有参构造函数的调用" << endl;
	}

	//拷贝构造函数(有参构造)
	Person(const Person& p) {
		//将传入的所有属性拷贝到当前身上
		age = p.age;
		cout << "Person 的拷贝构造函数的调用" << endl;
	}

	//析构函数
	~Person() {
		cout << "Person 析构函数的调用" << endl;
	}
	int age;

};

//调用
void test01() {
	//1.括号法
	Person p1;//默认构造函数的调用
	Person p2(10);//有参构造函数
	Person p3(p2);//拷贝构造函数
	//注意事项
	// 调用默认构造函数的时候,不要加()  Person p1();会认为是一个函数的声明
	
	//cout << "p2的年龄:" << p2.age << endl;
	//cout << "p3的年龄:" << p3.age << endl;

	//2.显示法
	Person p4;
	Person p5 = Person(10);//有参构造
	Person p6 = Person(p2);//拷贝构造
	//注意事项:
	//Person(10);匿名对象 特点:当前行执行结束后,系统会立即回收掉
	//所以你单独写时,会调用构造函数,并立刻销毁
	//不要利用拷贝构造函数初始化匿名对象   Person(p3)  编译器会认为Person(p3) == Person p3;
	
	//3.隐式转换法
	Person p7 = 10;//相当于 写了 Person p7 = Person(10);有参构造
	Person p8 = p7;//拷贝构造

}


int main() {
	test01();

	system("pause");
	return 0;
}

2.3 拷贝构造函数调用的时机

1.使用一个已经创建完毕的对象来初始化一个新对象

2.值传递的方式给构造函数参数传值

3.以值方式返回局部对象(注意新版VS中已经不再适用,不会再调用,两地址相同了)

eg.

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;

class Person {
public:
	Person() {
		cout << "Person默认构造函数调用" << endl;
	}
	Person(int age) {
		cout << "Person有参构造函数调用" << endl;
		m_Age = age;
	}
	Person(const Person& p) {
		cout << "Person拷贝构造函数调用" << endl;
		m_Age = p.m_Age;
	}
	~Person() {
		cout << "Person析构函数调用" << endl;
	}
	int m_Age;
};

//1.使用一个已经创建完毕的对象来初始化一个新对象
void test01() {
	Person p1(20);
	Person p2(p1);
	cout << "p2的年龄为:" << p2.m_Age << endl;

}
//2.值传递的方式给构造函数参数传值
void doWork(Person p) {
	//test02的p传给了这里的p就进行了拷贝
}

void test02() {
	Person p;
	doWork(p);

}

//3.以值方式返回局部对象,注意新版VS中已经不再适用,不会再调用,两地址相同了
Person doWork2() {
	Person p1;
	cout << (int*)&p1 << endl;
	return p1;
}

void test03() {
	Person p = doWork2();
	cout << (int*)&p << endl;
}


int main() {
	//test01();
	//test02();
	test03();

	system("pause");
	return 0;
}

2.4 构造函数的调用规则

1.默认构造函数(无参,函数体为空)

2..默认析构函数(无参,函数体为空)

3..默认拷贝构造函数,对属性值进行值拷贝

构造函数调用规则如下:
1.如果用户定义有参构造函数,c++不再提供默认无参构造,但是会提供默认拷贝构造函数

2.如果用户定义默认拷贝构造,c++不会提供其他构造函数

eg.

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;

class Person {
public:
	Person() {
		cout << "Person默认构造函数调用" << endl;
	}
	Person(int age) {
		cout << "Person有参构造函数调用" << endl;
		m_Age = age;
	}
	Person(const Person& p) {
		cout << "Person拷贝构造函数调用" << endl;
		m_Age = p.m_Age;
	}
	~Person() {
		cout << "Person析构函数调用" << endl;
	}
	int m_Age;
};

void test01() {
	Person p;
	p.m_Age = 18;

	Person p2(p);
	cout << "p2的年龄为:" << p2.m_Age << endl;
}


int main() {
	//test01();//如果不写拷贝构造,就会实现拷贝构造的空实现
	//如果用户定义有参构造函数,c++不再提供默认无参构造
	//如果用户定义默认拷贝构造,c++不会提供其他构造函数

	system("pause");
	return 0;
}

2.5 深拷贝与浅拷贝

浅拷贝:简单的赋值拷贝操作

深拷贝:在堆区重新申请空间进行拷贝操作

浅拷贝带来的问题

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;

class Person {
public:
	Person() {
		cout << "Person默认构造函数调用" << endl;
	}
	Person(int age,int height) {
		cout << "Person有参构造函数调用" << endl;
		m_Age = age;
		m_Height = new int(height);
	}

	~Person() {
		//将堆区的数据释放
		if (m_Height != NULL) {
			delete m_Height;
			m_Height = NULL;
		}
		cout << "Person析构函数调用" << endl;
	}
	int m_Age;
	int* m_Height;
};

void test01() {
	Person p1(18,160);

	cout << "p1的年龄为:" << p1.m_Age<<"身高为:"<<*p1.m_Height<<endl;

	Person p2(p1);//编译器给其做了一个浅拷贝
	cout << "p2的年龄为:" << p2.m_Age << "身高为:" << *p2.m_Height << endl;
}

int main() {
	test01();

	system("pause");
	return 0;
}

如上面代码所示,我并没有写拷贝构造,而是编译器自己进行默认拷贝,即为浅拷贝,在int m_Height上没有问题,但是在指针变量int *m_Height上,因为是在堆区上创建的,在该堆区地址上进行赋值,p1和p2指的是同一个地址,而p1,p2入栈后,p2先出来释放了该堆区地址,p1出来再次释放,从而导致错误

所以要利用深拷贝进行解决,即在堆区新开辟一个空间,代码如下

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;

class Person {
public:
	Person() {
		cout << "Person默认构造函数调用" << endl;
	}
	Person(int age,int height) {
		cout << "Person有参构造函数调用" << endl;
		m_Age = age;
		m_Height = new int(height);
	}
	Person(const Person &p) {
		cout << "Person拷贝构造函数调用" << endl;
		m_Age = p.m_Age;
		//m_Height = p.m_Height;编译器默认实现的代码
		m_Height = new int(*p.m_Height);
	}

	~Person() {
		//将堆区的数据释放
		if (m_Height != NULL) {
			delete m_Height;
			m_Height = NULL;
		}
		cout << "Person析构函数调用" << endl;
	}
	int m_Age;
	int* m_Height;
};

void test01() {
	Person p1(18,160);

	cout << "p1的年龄为:" << p1.m_Age<<"身高为:"<<*p1.m_Height<<endl;

	Person p2(p1);//编译器给其做了一个浅拷贝
	cout << "p2的年龄为:" << p2.m_Age << "身高为:" << *p2.m_Height << endl;
}

int main() {
	test01();

	system("pause");
	return 0;
}

2.6 初始化列表

作用:

c++提供了初始化列表语法,用来初始化属性

语法:

构造函数():属性1(值1),属性2(值2)...{}

 eg.

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;

class Person {
public:
	//传统初始化
	/*Person(int a,int b,int c) {
		m_A = a;
		m_B = b;
		m_C = c;
	}*/

	//初始化列表初始化属性
	Person(int a,int b,int c) :m_A(a), m_B(b), m_C(c) {

	}


	int m_A;
	int m_B;
	int m_C;

};

void test01() {
	Person p(10, 20, 30);


	cout << "m_A = " << p.m_A << endl;
	cout << "m_B = " << p.m_B << endl;
	cout << "m_C = " << p.m_C << endl;
}

int main() {
	test01();

	system("pause");
	return 0;
}

2.7 类对象作为类成员

C++类中的成员可以是另一个类的对象,我们称为 对象成员

class A{};
class B{
    A a;
};

B类中有对象A作为成员,A为对象成员,那么创建B的时候,A与B的构造与析构顺序?

显然是A。当其他类对象作为本类成员,构造时候先构造类对象,再构造自身,析构入栈顺序不变,先进去类对象再进去自身,所以自身先出来,类对象后出来,看上去顺序相反

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;

class Phone {
public:
	Phone(string pName) {
		m_PName = pName;
		cout << "Phone构造函数调用" << endl;
	}
	~Phone() {
		cout << "Phone析构函数调用" << endl;
	}

	string m_PName;

};

class Person {
public:
	//Phone m_Phone = pName;隐式转化法
	Person(string name, string pName):m_Name(name),m_Phone(pName) {
		cout << "Person构造函数调用" << endl;
	}
	~Person(){
		cout << "Person析构函数调用" << endl;
	}
	string m_Name;
	Phone m_Phone;
};

void test01() {
	Person p("张三", "华为");
	cout << p.m_Name << "拿着" << p.m_Phone.m_PName << endl;
}

int main() {
	test01();

	system("pause");
	return 0;
}

2.8 静态成员

静态成员就是在成员函数前加上关键字static,称为静态成员

静态成员分为:

1.静态成员变量

        1.1所有对象共享同一份数据

        1.2在编译阶段分配内存

        1.3类内声明,类外初始化

2.静态成员函数:

        2.1所有对象共享同一函数

        2.2静态成员函数只能访问静态成员变量

eg静态成员变量.

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;

class Person {
public:
	//1 所有对象都共享同一份数据
	//2 编译阶段就分配内存
	//3 类内声明,类外初始化操作
	static int m_A;

	//静态成员变量也是有访问权限的
private:
	static int m_B;

};

 int Person::m_A = 100;
 int Person::m_B = 200;

void test01() {
	Person p;
	cout << p.m_A << endl;

	Person p2;
	p2.m_A = 200;
	cout << p.m_A << endl;
}

void test02() {
	//静态成员变量,不属于某个对象上,所有对象都共享同一份数据
	//因此静态成员变量有两种访问方式
	//1.通过对象访问
	//Person p;
	//cout << p.m_A << endl;

	//2.通过类名访问
	cout << Person::m_A << endl;

	//cout << Person::m_B << endl;类外不可访问私有变量
}

int main() {
	
	//test01();
	test02();

	system("pause");
	return 0;
}

eg静态成员函数.

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string.h>
using namespace std;

class Person {
	//静态成员函数只能访问静态成员变量
public:
	static void func() {
		m_A = 100;
		//m_B = 200;会报错 静态成员函数 不可以访问 非静态成员变量
		//无法区分到底是哪个对象的m_B属性
		cout << "static void func调用" << endl;
	}
	static int m_A;
	int m_B;

	//静态成员函数也是有访问权限的
private:
	static void func() {
		m_A = 200;
		//m_B = 200;会报错 静态成员函数 不可以访问 非静态成员变量
		//无法区分到底是哪个对象的m_B属性
		cout << "static void func2调用" << endl;
	}

};

int Person::m_A = 0;


void test01() {
	//1、通过对象访问
	//Person p;
	//p.func();
	//2、通过类名访问
	Person::func();

	//Person::func2();类外无法访问
}

int main() {
	test01();


	system("pause");
	return 0;
}

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

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

相关文章

ROS参数服务器

一、介绍 参数服务器是用于存储和检索参数的分布式多机器人配置系统&#xff0c;它允许节点动态地获取参数值。 在ROS中&#xff0c;参数服务器是一种用于存储和检索参数的分布式多机器人配置系统。它允许节点动态地获取参数值&#xff0c;并提供了一种方便的方式来管理和共享配…

【智能算法应用】模拟退火算法求解多车型车辆路径问题HFVRP

目录 1.算法原理2.多车型车辆路径HFVRP数学模型3.结果展示4.参考文献5.代码获取 1.算法原理 模拟退火算法&#xff08;Simulated Annealing, SA&#xff09;是一种通用概率算法&#xff0c;用于在给定一个大的搜索空间内寻找问题的近似最优解。这种算法受到物理中退火过程的启…

Jenkins + github 自动化部署配置

1 Jenkins安装 AWS EC2安装Jenkins&#xff1a;AWS EC2 JDK11 Jenkins-CSDN博客 AWS EC2上Docker安装Jenkins&#xff1a;https://blog.csdn.net/hhujjj2005/article/details/139078402 2 登录jenkins http://192.168.1.128:8080/ $ docker exec -it d1851d9e3386 /bin/ba…

【MySQL】库的基础操作

&#x1f30e;库的操作 文章目录&#xff1a; 库的操作 创建删除数据库 数据库编码集和校验集 数据库的增删查改       数据库查找       数据库修改 备份和恢复 查看数据库连接情况 总结 前言&#xff1a;   数据库操作是软件开发中不可或缺的一部分&#xff0…

labelme语义分割标注

参考&#xff1a;同济子豪兄 https://github.com/TommyZihao/MMSegmentation_Tutorials GitHub - TommyZihao/Train_Custom_Dataset: 标注自己的数据集&#xff0c;训练、评估、测试、部署自己的人工智能算法 下载安装Labelme Labelme主页&#xff1a;https://github.com/wke…

linux开放某一个端口具体步骤

场景&#xff1a;当服务器防火墙不能直接关闭&#xff0c;但是客户端必须要访问服务器某一个端口时。 处理&#xff1a;对服务器端进行处理&#xff0c;只将该端口开放出来让客户端访问 本地使用vm安装了一个centos服务器&#xff0c;ip地址是 192.168.200.130。在这里充当服…

考研数学|线代跟谁好,李永乐,汤家凤还是张宇?

如果线代基础不好&#xff0c;那建议开刚开始的时候听汤家凤老师的线代课程 汤家凤教授的线性代数课程常被忽视&#xff0c;多数人倾向于去听李永乐。然而&#xff0c;在我考研的过程中&#xff0c;我曾尝试听李永乐教老师的课&#xff0c;可能是由于我自身基础薄弱&#xff0…

vscode远程连接Ubuntu mysql服务器

注意&#xff1a;刚开始使用root用户死活连接不上&#xff0c;可能就是root用户没有权限的问题&#xff0c;可以尝试创建一个新的数据库用户&#xff0c;授予权限进行连接 ubuntu安装mysql 创建新用户 执行&#xff1a;sudo apt-get install mysql-server安装服务器(yum) 执…

Intel HDSLB 高性能四层负载均衡器 — 基本原理和部署配置

目录 文章目录 目录前言HDSLB-DPVS 的基本原理LVSDPDKDPVSHDSLB-DPVS HDSLB 的部署配置硬件要求软件要求编译安装 DPDK编译安装 HDSLB-DPVS配置大页内存配置网卡配置 HDSLB-DPVS启动 HDSLB-DPVS 测试 HDSLB-DPVS Two-arm Full-NAT 模式问题分析最后 前言 在上一篇《Intel HDSL…

TCP/IP协议(一)

一.报文和协议 协议有什么作用&#xff1f;协议定义通信实体间所交换报文的格式和次序&#xff0c;以及在报文发送和/或接收或者其他事件方面所采取的行动(响应)。 什么是报文&#xff1f;指在网络中传输的数据单元&#xff0c;网络通讯的基本单位。&#xff08;HTTP报文、TCP报…

【C语言】10.C语言指针(1)

文章目录 1.内存和地址1.1 内存1.2 究竟该如何理解编址 2.指针变量和地址2.1 取地址操作符&#xff08;&&#xff09;2.2 指针变量和解引⽤操作符&#xff08;*&#xff09;2.2.1 指针变量2.2.2 如何拆解指针类型2.2.3 解引⽤操作符 2.3 指针变量的⼤⼩ 3.指针变量类型的意…

中科蓝讯AB32VG1中文寄存器说明GPIO端口操作

1 GPIO管理 1.1 GPIO通用控制寄存器 寄存器 1- 1 GPIOA&#xff1a;端口 A 数据寄存器 位寄存器名模式缺省描述31:8---未使用7:0GPIOA写0x00PAx 数据。当 PAx 用作 GPIO 时有效 0&#xff1a;读取时PAx为输入低电平状态&#xff0c;写入时PAx为输出低电平; 1&#xff1a;PAx…

中间件-------RabbitMQ

同步和异步 异步调用 MQ MQ优势&#xff1a;①服务解耦 ②异步调用 ③流量削峰 结构 消息模型 RabbitMQ入门案例&#xff0c;实现消息发送和消息接收 生产者&#xff1a; public class PublisherTest {Testpublic void testSendMessage() throws IOException, TimeoutExce…

【Text2SQL 论文】SeaD:使用 Schema-aware 去噪训练的 end2end 的 Text2SQL

论文&#xff1a;SeaD: End-to-end Text-to-SQL Generation with Schema-aware Denoising ⭐⭐ NAACL 2022, arXiv:2105.07911 本论文提出 SeaD 模型&#xff0c;使用 schema-aware 的去噪方法来训练一个 end2end、seq2seq 的 Transformer 模型来实现 Text2SQL。 一、论文速读…

[vue error] vue3中使用同名简写报错 ‘v-bind‘ directives require an attribute value

错误详情 错误信息 ‘v-bind’ directives require an attribute value.eslintvue/valid-v-bind 错误原因 默认情况下&#xff0c;ESLint 将同名缩写视为错误。此外&#xff0c;Volar 扩展可能需要更新以支持 Vue 3.4 中的新语法。 解决方案 更新 Volar 扩展 安装或更新 …

Springboot集成GRPC

Springboot集成GRPC 一、springboot版本二、GRPC的pom依赖2.1 服务端2.2 客户端3.构建依赖 三、配置文件服务端客户端 四、 demo4.1 编写proto文件4.2 生成文件4.3 服务端重写方法4.4 客户端调用该方法 五、测试 一、springboot版本 <groupId>org.springframework.boot&l…

YOLOv8_pose预测流程-原理解析[关键点检测理论篇]

YOLOv8_seg的网络结构图在博客YOLOv8网络结构介绍_CSDN博客已经更新了,由网络结构图可以看到相对于目标检测网络,实例分割网络只是在Head层不相同,如下图所示,在每个特征层中增加了KeyPoint分支(浅绿色),通过两个卷积组和一个Conv卷积得到得到通道数为51的特征图,51表示…

自动驾驶技术现状与需求分析

随着科技的不断进步和智能化浪潮的席卷&#xff0c;自动驾驶技术已成为当今交通领域的热点话题。本文旨在深入探讨自动驾驶技术的当前发展状况&#xff0c;并对其未来的市场需求进行细致分析。首先&#xff0c;我们将回顾自动驾驶技术的起源、发展历程以及当前的技术水平&#…

信息学奥赛初赛天天练-12-数论-整除问题

更多资源请关注纽扣编程微信公众号 整除的性质 1 整除性 若 &#x1d44e; 和 &#x1d44f; 都为整数&#xff0c; &#x1d44e; 整除 &#x1d44f; 是指 &#x1d44f; 是 &#x1d44e; 的倍数&#xff0c;&#x1d44e; 是 &#x1d44f; 的约数&#xff08;或者叫 因…

贪心题目总结

1. 最长递增子序列 我们来看一下我们的贪心策略体现在哪里&#xff1f;&#xff1f;&#xff1f; 我们来总结一下&#xff1a; 我们在考虑最长递增子序列的长度的时候&#xff0c;其实并不关心这个序列长什么样子,我们只是关心最后一个元素是谁。这样新来一个元素之后&#xf…