C++的类和对象

news2024/12/25 23:51:56

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;
}

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

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

相关文章

需求分析部分图形工具

描述复杂的事物时,图形远比文字叙述优越得多,它形象直观容易理解。前面已经介绍了用于建立功能模型的数据流图、用于建立数据模型的实体-联系图和用于建立行为模型的状态图,本节再简要地介绍在需求分析阶段可能用到的另外3种图形工具。 1 层次方框图 层次方框图用树形结…

开源模型应用落地-LangSmith试炼-入门初体验-数据集评估(三)

一、前言 LangSmith是一个用于构建生产级 LLM 应用程序的平台&#xff0c;它提供了调试、测试、评估和监控基于任何 LLM 框架构建的链和智能代理的功能&#xff0c;并能与LangChain无缝集成。通过使用LangSmith帮助开发者深入了解模型在不同场景下的表现&#xff0c;让开发者能…

论文阅读_管理模型的记忆_MemGPT

1 2 3 4 5 6 7 8 9英文名称: MemGPT: Towards LLMs as Operating Systems 中文名称: MemGPT&#xff1a;将LLMs打造成操作系统 链接: https://arxiv.org/abs/2310.08560 代码: https://github.com/cpacker/MemGPT 作者: Charles Packer, Sarah Wooders, Kevin Lin, Vivian Fang…

推荐10款优秀的组件库(一)

1.Ant Desgin UI 网址&#xff1a; https://ant-design-mobile.antgroup.com/zh Ant Design - 一套企业级 UI 设计语言和 React 组件库 "Ant Design Mobile"是一个在线的移动端Web体验平台&#xff0c;让你探索移动端Web的体验极限。 添加图片注释&#xff0c;不…

安全设计 | 安全设计不得马虎!微软STRIDE威胁建模方法让你事半功倍,快速发现应用安全隐患!

STRIDE威胁建模方法最早发表于2006年11月的《MSDN杂志》&#xff0c;作者是微软的工程师Shawn Hernan、Scott Lambert 、Tomasz Ostwald 和 Adam Shostack。那我们为什么要进行威胁建模&#xff1f; 如何使用数据流图对系统进行威胁建模&#xff1f;如何减轻威胁&#xff1f;接…

STM32F1之OV7725摄像头

目录 1. 摄像头简介 2. OV7725 摄像头简介 3. OV7725 引脚 4. OV7725 功能框架图 5. SCCB时序 5.1 SCCB 的起始、停止信号及数据有效性 5.2 SCCB 数据读写过程 1. 摄像头简介 在各类信息中&#xff0c;图像含有最丰富的信息&#xff0c;作为机…

从0开始学统计-蒙彼利埃尔悖论与条件概率

1.什么叫均衡可比&#xff1f; "均衡可比"指的是在进行比较时&#xff0c;确保所比较的对象或情况具有相似的特征和条件&#xff0c;以保持比较的公正性和准确性。这个概念通常应用于研究设计和数据分析中&#xff0c;以确保比较结果的可信度和有效性。 在研究中&a…

HTML静态网页成品作业(HTML+CSS)——企业酒店官网网页(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有5个页面。 二、作品演示 三、代…

SpringCloud系列(26)--OpenFeign超时控制

前言&#xff1a;在上一章节中我们简单的介绍了如何使用OprnFeign去调用微服务&#xff0c;因为消费侧和服务侧是两个不同的微服务&#xff0c;这样可能会出现超时的现象&#xff0c;例如服务侧需要3秒处理任何才能返回结果&#xff0c;但消费侧可能2秒就断开连接了&#xff0c…

C++代码错误解决1(函数模板)

1、代码如下 //示例函数模板的使用 #include <iostream> #include <string> using namespace std; template <typename T>//函数模板 T max(T a,T b) {return a>b?a:b; } int main() {int a,b;cout<<"input two integers to a&b:"…

文章解读与仿真程序复现思路——电力系统保护与控制EI\CSCD\北大核心《计及温控厌氧发酵和阶梯碳交易的农村综合能源低碳经济调度》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

如何处理时间序列的缺失数据

您是否应该删除、插入或估算&#xff1f; 世界上没有完美的数据集。每个数据科学家在数据探索过程中都会有这样的感觉&#xff1a; df.info()看到类似这样的内容&#xff1a; 大多数 ML 模型无法处理 NaN 或空值&#xff0c;因此如果您的特征或目标包含这些值&#xff0c;则在…

自己手写一个单向链表【C风格】

//单链表 #include <iostream> #define MAX_SIZE 20 #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0typedef int ElemType;//元素的类型 typedef int Status;//返回状态typedef struct Node {ElemType data;//链表中保存的数据struct Node* next;//指向下…

【字典树(前缀树) 异或 离线查询】1707. 与数组中元素的最大异或值

本文涉及知识点 字典树&#xff08;前缀树&#xff09; 位运算 异或 离线查询 LeetCode1707. 与数组中元素的最大异或值 给你一个由非负整数组成的数组 nums 。另有一个查询数组 queries &#xff0c;其中 queries[i] [xi, mi] 。 第 i 个查询的答案是 xi 和任何 nums 数组…

自定义一个复杂的React Table表格组件-06

前面基本了解了组件的基本用法&#xff0c;在本节会实现一个更高级的例子。另外需要注意本节代码是采用V15版本的createClass()、React.DOM和JSX实现的&#xff0c;有时间的同学可以改成类实现的方式。 html的世界中最复杂的UI控制就是表格了&#xff0c;原因是table它依赖本地…

Vitis HLS 学习笔记--控制驱动TLP-处理deadlock

目录 1. 简介 2. 代码解析 2.1 HLS kernel代码 2.2 查看接口报告 2.3 TestBench 2.4 Dataflow 报告 3. Takeaways 4. 总结 1. 简介 本文是对《Hardware Acceleration Tutorials: FIFO Sizing for Performance and Avoiding Deadlocks》实验内容的详细解释。 首先需要…

AI视频教程下载:用提示工程在GPT商店构建10个GPTs

你将学到什么&#xff1f; 深入了解ChatGPT平台和GPT商店的生态系统。 开发为多样化应用定制GPT模型的专业知识。 掌握高效内容生成的AI自动化技术。 学习高级提示工程以优化ChatGPT输出。 获取构建AI驱动的数字营销和广告解决方案的技能。 了解如何为SEO写作和优化创建专…

从0开始学统计-多个婴儿连续夭折是谋杀吗?

1.什么是小概率事件&#xff1f; 小概率事件是指在一次随机试验中发生概率非常低的事件。一般来说&#xff0c;小概率事件的发生概率远低于一定的阈值&#xff0c;通常取0.05或0.01。在统计学中&#xff0c;这些阈值被称为显著性水平&#xff08;significance level&#xff0…

CIC滤波器

CIC滤波器结构简单&#xff0c;没有乘法器&#xff0c;只有加法器、积分器和寄存器&#xff0c;适合工作在高抽样率条件下&#xff0c;而且CIC滤波器是一种基于零点相消的FIR滤波器。 CIC滤波器分为单级和多级滤波器。 1.在单极滤波器中&#xff1a; 当CIC滤波器的长度M远大于…

【css3】04-css3转换

目录 1 2D转换 2 3D转换 3 案例&#xff1a;旋转的魔方 1 2D转换 ## 2D转换 ☞ 位移 transform: translate(100px,100px); 备注&#xff1a; 位移是相对元素自身的位置发生位置改变 ☞ 旋转 transform: rotate(60deg); 备注&am…