C++核心编程——类和对象(二)

news2024/10/1 17:33:51

本专栏记录C++学习过程包括C++基础以及数据结构和算法,其中第一部分计划时间一个月,主要跟着黑马视频教程,学习路线如下,不定时更新,欢迎关注
当前章节处于:
---------第1阶段-C++基础入门
---------第2阶段实战-通讯录管理系统,
=====>第3阶段-C++核心编程
---------第4阶段实战-基于多态的企业职工系统
---------第5阶段-C++提高编程
---------第6阶段实战-基于STL泛化编程的演讲比赛
---------第7阶段-C++实战项目机房预约管理系统

文章目录

  • 一、友元
    • 1.1 全局函数做友元
    • 1.2 类做友元
    • 1.3 全局函数做友元
  • 二、运算符重载
    • 2.1 加号运算符重载
    • 2.2 左移运算符重载
    • 2.3 递增运算符重载
    • 2.4 赋值运算符重载
    • 2.5 关系运算符重载
    • 2.6 函数调用运算符重载
  • 三、继承
    • 3.1 继承概述
    • 3.2 继承方式
    • 3.3 继承中的对象模型
    • 3.4 继承构造和析构顺序
    • 3.5 继承同名成员处理方式
    • 3.6 继承同名静态成员
    • 3.7 多继承
    • 3.8 菱形继承
  • 四、多态
    • 4.1 多态基本概念
    • 4.2 纯虚函数和抽象类
    • 4.3 虚析构和纯虚析构

一、友元

在程序里,有些私有属性也想让类外特殊的有些函数或者类进行访问,就需要用到友元的技术,目的是让一个函数或者类访问另一个类中私有成员。关键词为friend,友元的是三种实现:

  • 全局函数做友元
  • 类做友元
  • 成员函数做友元

1.1 全局函数做友元

#include <iostream>
using namespace std;

class Person {
	friend void test();  // 申明友元
public:
	Person() {
		name = "张三";
		gender = "男";
	}
	string name;

private:
	string gender; // 私有属性
};

void test() {
	Person p;
	cout << "姓名:" << p.name << endl;
	cout << "性别:" << p.gender << endl;
}
// 定义友元函数
int main() {
	test();
	system("pause");
	return 0;

}
姓名:张三
性别:男
请按任意键继续. . .

1.2 类做友元

#include <iostream>
using namespace std;
class Student {
	friend class Teacher; // 类做友元
public:
	Student() {
		name = "张三";
		score = 100;
	}
	string name;
private:
	int score;
};
class Teacher {
public:
	void test(Student stu) {
		cout << "学生姓名:" << stu.name << endl;
		cout << "学生分数:" << stu.score << endl;
	}
};

int main() {
	Student stu;
	Teacher teacher;

	teacher.test(stu);
	system("pause");
	return 0;

}
学生姓名:张三
学生分数:100
请按任意键继续. . .

1.3 全局函数做友元

#include <iostream>
using namespace std;
class Student;
class Teacher;
class Teacher {
public:
	Teacher();
public:
	void test();
	void test2();
	Student* stu;
};


class Student {
	friend void Teacher::test(); // 成员函数做友元
public:
	Student();
public:
	string name;
private:
	int score;
};
Student::Student() {
	name = "张三";
	score = 100;
} // 写在Teacher构造函数之前

Teacher::Teacher() {
	stu = new Student;
}
void Teacher::test() {
	cout << "学生姓名:" << stu->name << endl;
	cout << "学生分数:" << stu->score << endl;
}
void Teacher::test2() {
	cout << "学生姓名:" << stu->name << endl;
	//cout << "学生分数:" << stu->score << endl;
}

int main() {
	Teacher teacher;
	teacher.test();
	system("pause");
	return 0;

}
学生姓名:张三
学生分数:100
请按任意键继续. . .

二、运算符重载

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

  • 对于内置的数据类型的表达式的运算符是不可能改变的
  • 不要滥用运算符重载

2.1 加号运算符重载

#include <iostream>
using namespace std;
class Person {
public:
	int m_A = 0;
	int m_B = 0;
	Person() {

	}
	Person(int a,int b) {
		m_A = a;
		m_B = b;
	}
	// 成员函数加号运算符重载
	Person operator+(const Person& p2) { // 用引用节省内存
		Person temp;
		temp.m_A = this->m_A + p2.m_A;
		temp.m_B = this->m_B + p2.m_B;
		return temp;
	}
};
// 全局函数加号运算符重载
//Person operator+(const Person &p1,const Person &p2) { // 用引用节省内存
//	Person temp;
//	temp.m_A = p1.m_A + p2.m_A;
//	temp.m_B = p1.m_B + p2.m_B;
//	return temp;
//}


int main() {
	Person p1(1, 2);
	Person p2(3, 4);
	Person p3 = p1 + p2;
	cout << "p3.m_A=" << p3.m_A << "  p3.m_B=" << p3.m_B << endl;
	system("pause");
	return 0;

}
p3.m_A=4  p3.m_B=6
请按任意键继续. . .
在这里插入代码片

2.2 左移运算符重载

#include <iostream>
using namespace std;
class Person {
	friend ostream& operator<<(ostream& cout,const Person& p);
public:
	Person(int a,int b) {
		m_A = a;
		m_B = b;
	}
private:
	int m_A;
	int m_B;
};

// 重载左移运算符
ostream& operator<<(ostream &cout,const Person &p) {
	cout << "p.m_A=" << p.m_A << "  p.m_B=" << p.m_B;
	return cout;
}
int main() {
	Person p(10, 20);
	cout << p << endl;
	system("pause");
	return 0;

}
p.m_A=10  p.m_B=20
请按任意键继续. . .

2.3 递增运算符重载

#include <iostream>
using namespace std;

class MyInt {
	friend ostream& operator<<(ostream& cout, const MyInt& p);
public:
	MyInt(){}
	MyInt(int a) {
		num = a;
	}
	// 重载++前置运算
	MyInt& operator++() {
		num++;
		return *this;
	}
	// 重载++后置运算
	MyInt operator++(int) { // int 占位符表示后置++
		MyInt temp = *this; // 存储当前num
		num++;
		return temp; // 返回局部变量,只能以值的方式返回
	}
private:
	int num;
};
ostream& operator<<(ostream& cout, const MyInt& p) {
	cout << "num=" << p.num;
	return cout;
}
// 测试前置++
void test1() {
	MyInt a(10);
	cout << ++a << endl;
	cout << a << endl;

}
// 测试后置++
void test2() {
	MyInt a(10);
	cout << a++ << endl;
	cout << a << endl;

}
int main() {
	cout << "测试前置++:" << endl;
	test1();
	cout << "测试后置++:" << endl;
	test2();
	system("pause");
	return 0;

}
测试前置++:
num=11
num=11
测试后置++:
num=10
num=11
请按任意键继续. . .

2.4 赋值运算符重载

#include <iostream>
using namespace std;
class Person {
	friend void test();
public:
	Person(){}
	Person(int a) {
		age = new int(a); // 在堆区存放a
	}
	// 析构函数
	~Person() {
		if (age != NULL) {
			delete age;
			age = NULL;
		}
	}
	// 重构赋值运算符
	Person& operator=(Person &p) {
		age = new int(*p.age);
		return *this;
	}
private:
	int *age;
};



void test() {
	Person p1(10);
	Person p2(20);
	p1 = p2; //不报错,深拷贝重新申请一片地址
	cout << "p1=" << *p1.age << endl;
}



int main() {
	test();
	system("pause");
	return 0;

}
p1=20
请按任意键继续. . .

2.5 关系运算符重载

重载关系运算符,可以让两个自定义类型对象进行对比操作

#include <iostream>
using namespace std;
class Person {
public:
	string name;
	int age;
	Person(string n,int a) {
		name = n;
		age = a;
	}
	bool operator==(Person p) {
		if ((name == p.name) && (age == p.age)) {
			return true;
		}
		else {
			return false;
		}
	}
};

void test() {
	Person p1("A", 12);
	Person p2("A", 12);
	if (p1 == p2) {
		cout << "p1和p2相等!" << endl;
	}
	else {
		cout << "p1和p2不相等" << endl;
	}
}

int main() {
	test();
	system("pause");
	return 0;

}
p1和p2相等!
请按任意键继续. . .

2.6 函数调用运算符重载

  • 函数调用运算符()也可以重载
  • 由于重载后使用的方式非常像函数的调用,因此称为仿函数
  • 仿函数没有固定写法,非常灵活
#include <iostream>
using namespace std;

class MyPrint {
public:
	// 重载函数调用运算符
	void operator()(string test) {
		cout << test << endl;
	}
};
int main() {
	MyPrint myprint;
	myprint("Hello World");
	system("pause");
	return 0;

}
Hello World
请按任意键继续. . .

三、继承

3.1 继承概述

继承的好处:可以减少重复的代码。
语法:class 子类 :继承方式 父类
子类也称为派生类,父类也称为基类。
子类中的成员,包括两大部分:一类是从基类继承过来的(表现共性),一类是自己增加的成员(体现个形)

#include <iostream>
using namespace std;
class Animal {
public:
	void eat() {
		cout << "吃东西!" << endl;
	}
	void play() {
		cout << "出去玩!" << endl;
	}
};
class Cat :public Animal {  // 继承父类
public:
	void drink() {
		cout << "小猫喝水!" << endl;
	}
};
int main() {
	Cat cat;
	cat.eat();
	cat.play();
	cat.drink();
	system("pause");
	return 0;

}
吃东西!
出去玩!
小猫喝水!
请按任意键继续. . .

3.2 继承方式

继承方式包括三种:

  • 公共继承
  • 保护继承
  • 私有继承

继承关系如下:
在这里插入图片描述

#include <iostream>
using namespace std;
// 父类
class Base1 {
public :
	int a;
protected:
	int b;
private:
	int c;
};
// 子类 继承方式为public
class Son1 : public Base1 {
public:
	void func() {
		a = 100;
		b = 100;
		//c = 100;// 报错,父类private不可访问
	}
};
// 继承方式为protected
class Son2 : protected Base1 {
public:
	void func() {
		a = 100;
		b = 100;
		//c = 100;// 报错,父类private不可访问
	}
};
// 继承方式为private
class Son3 : private Base1 {
public:
	void func() {
		a = 100;
		b = 100;
		//c = 100;// 报错,父类private不可访问
	}
};
int main() {
	Son2 s2;
	//s2.a = 100; // 报错
	//s2.b = 100; // 报错,子类继承为protected,类外不可访问
	Son3 s3;
	//s3.a = 100; // 报错
    //s3.b = 100; // 报错,子类继承为private,类外不可访问
	system("pause");
	return 0;

}

3.3 继承中的对象模型

从父类继承过来的成员,哪些属于子类对象中?

#include <iostream>
using namespace std;

class Base1 {
public:
	int a;
protected:
	int b;
private:
	int c;
};
// 子类 继承方式为public
class Son1 : public Base1 {
public:
	int s;
	
};
int main() {
	Son1 s1;
	cout << "sizeof s1=" << sizeof(s1) << endl;   // 16 继承了父类中的所有非静态成员属性,但是private被编译器隐藏无法访问
	system("pause");
	return 0;

}
sizeof s1=16
请按任意键继续. . .

3.4 继承构造和析构顺序

#include <iostream>
using namespace std;

class Base{
public:
	int a;
	Base() {
		cout << "Base的构造函数" << endl;
	}
	~Base() {
		cout << "Base的析构函数" << endl;
	}
protected:
	int b;
private:
	int c;
};
class Son1 : public Base {
public:
	int s;
	Son1() {
		cout << "Son1的构造函数" << endl;
	}
	~Son1() {
		cout << "Son1的析构函数" << endl;
	}
};
void test() {
	Son1 s1;
}
int main() {
	test();
	system("pause");
	return 0;

}
Base的构造函数
Son1的构造函数
Son1的析构函数
Base的析构函数
请按任意键继续. . .

现有父类构造再有子类构造,然后子类析构,最后父类析构

3.5 继承同名成员处理方式

  • 访问子类同名成员,直接访问即可
  • 访问父类同名成员,需要加作用域
#include <iostream>
using namespace std;

class Base {
public:
	int a;
	Base() {
		a = 100;
	}

};
class Son1 : public Base {
public:
	int a;
	Son1() {
		a = 200;
	}
};
void test() {
	Son1 s1;
	cout << "调用Son中的a:" << s1.a << endl;
	cout << "调用Base中的a:" << s1.Base::a << endl;
}
int main() {
	test();
	system("pause");
	return 0;

}
调用Son中的a:200
调用Base中的a:100
请按任意键继续. . .

成员函数也是一样,当继承了相同名称的同名函数时,编译器会将父类的同名函数隐藏,想要调用父类的同名函数需要添加作用域。

3.6 继承同名静态成员

#include <iostream>
using namespace std;

class Base {
public:
	static int a;
};

int Base::a = 100;
class Son1 : public Base {
public:
	static int a;
};
int Son1::a = 200;


void test() {
	Son1 s1;
	// 实例化调用
	cout << "调用Son中的a:" << s1.a << endl;
	cout << "调用Base中的a:" << s1.Base::a << endl;
	// 类名调用
	cout << "调用Son中的a:" << Son1::a << endl;
	cout << "调用Base中的a:" << Son1::Base::a << endl;
}
int main() {
	test();
	system("pause");
	return 0;

}
调用Son中的a:200
调用Base中的a:100
调用Son中的a:200
调用Base中的a:100
请按任意键继续. . .

静态成员函数也是同理

3.7 多继承

语法: class 子类:继承方式 父类1 ,继承方式 父类2...
多继承可能会引发父类中有同名成员出现,需要加作用域区分。
实际开发中不建议使用多继承

#include <iostream>
using namespace std;

class Base1 {
public:
	Base1() {
		a = 100;
	}
	int a;
};
class Base2 {
public:
	Base2() {
		a = 200;
	}
	int a;
};

class Son1 : public Base1,public Base2 {
public:
	int a;
	Son1() {
		a = 300;
	}
};

int main() {
	Son1 s1;
	cout << "Son1 中的a:" <<s1.a<< endl;
	cout << "Base1 中的a:" <<s1.Base1::a<< endl;
	cout << "Base2 中的a:" <<s1.Base2::a << endl;
	system("pause");
	return 0;

}
Son1 中的a:300
Base1 中的a:100
Base2 中的a:200
请按任意键继续. . .

3.8 菱形继承

菱形继承概念:

  • 两个派生类继承同一个基类
  • 又有某个类同时继承这两个派生类

这种继承被称为菱形继承或者钻石继承
在这里插入图片描述

#include <iostream>
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 test() {
	SheepTuo t1;
	t1.Sheep::age = 100;
	t1.Tuo::age = 200;
	cout << "t1.Sheep::age   " << t1.Sheep::age << endl; 
	cout << "t1.Tuo::age   " << t1.Tuo::age << endl;
}
int main() {
	test();
	system("pause");
	return 0;

}
t1.Sheep::age   200
t1.Tuo::age   200
请按任意键继续. . .

四、多态

4.1 多态基本概念

多态是C++面向对象三大特性之一一
多态分为两类:

  • 静态多态:函数重载和运算符重载属于静态多态,复用函数名
  • 动态多态:派生类和虚函数实现运行时多态

静态多态和动态多态区别:

  • 静态多态的函数地址早绑定——编译阶段确定函数地址
  • 动态多态的函数地址晚绑定——运行阶段确定函数地址
#include <iostream>
using namespace std;

class Animal {
public:
	// 实现晚绑定
	virtual void speak() {
		cout << "动物在说话" << endl;
	}
};

class Dog :public Animal {
public:
	void speak() {
		cout << "小狗在说话" << endl;
	}
};

class Cat :public Animal {
public:
	void speak() {
		cout << "小猫在说话" << endl;
	}
};
// 必须是引用
void doSpeak(Animal &animal) {
	animal.speak();
}
int main() {
	Cat cat;
	doSpeak(cat);
	Dog dog;
	doSpeak(dog);
	system("pause");
	return 0;

}
小猫在说话
小狗在说话
请按任意键继续. . .

多态需要满足条件

  • 有继承关系
  • 子类重写父类中的虚函数

多态的使用条件
父类指针或应用指向子类对象
在这里插入图片描述
实战案例

#include <iostream>
using namespace std;
class Caulater {
public:
	int num1;
	int num2;
	virtual int getresult() {
		// 空实现
		return 0;
	}
};

// 加法
class CaulaterAdd:public Caulater {
public:
	int getresult() {
		return num1 + num2;
	}
};

// 减法
class CaulaterJian :public Caulater {
public:
	int getresult() {
		return num1 - num2;
	}
};


// 乘法
class CaulaterChen :public Caulater {
public:
	int getresult() {
		return num1 * num2;
	}
};


void test(Caulater &c) {
	CaulaterAdd ad;
	ad.num1 = 10;
	ad.num2 = 10;
	cout << ad.getresult() << endl;

}
int main() {
	Caulater c;
	test(c);
	system("pause");
	return 0;

}
20
请按任意键继续. . .

4.2 纯虚函数和抽象类

在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容,因此可以将虚函数改为纯虚函数。当类中有纯虚函数,这个类也称为抽象类
抽象类特点:

  • 无法实例化对象
  • 子类必须重写抽象类中的纯虚函数,否则也属于抽象类
#include <iostream>
using namespace std;
class Base {
public:
	// 纯虚函数,该类叫抽象类
	virtual void func() = 0;
};

class Son:public Base {
public:
	void func() {
		cout << "调用func函数!" << endl;
	}
};

int main() {
	//Base b;// 抽象类无法实例化对象
	Base * base = new Son;
	Son s; // 重写纯虚函数后可以实例化对象,否则子类也是抽象类不能实例化对象
	base->func();
	system("pause");
	return 0;

}
调用func函数!
请按任意键继续. . .

实战案例
要求:利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶。

#include <iostream>
using namespace std;


// 饮品抽象类
class Drink {
public:
	virtual void func() = 0;
};
// 咖啡子类
class Coffee :public Drink {
public:
	void func() {
		cout << "制作咖啡!" << endl;
	}
};
// 茶叶子类
class Tea :public Drink {
public:
	void func() {
		cout << "制作茶叶!" << endl;
	}
};


int main() {
	Drink* c = new Coffee;
	c->func();
	Drink* t = new Tea;
	t->func();
	system("pause");
	return 0;

}
制作咖啡!
制作茶叶!
请按任意键继续. . .

4.3 虚析构和纯虚析构

多态中,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码,需要将父类中的析构函数改为虚析构或者纯虚析构
虚析构和纯虚析构共性:

  • 可以解决父类指针释放子类对象
  • 都需要有具体的函数实现

虚析构和纯虚析构的区别
如果是纯虚析构,该类属于抽象类,无法实例化对象

#include <iostream>
using namespace std;
class Base {
public:
	Base() {
		cout << "Base的构造函数!" << endl;
	}
	// 虚析构函数
	//virtual ~Base() {
	//	cout << "Base的析构函数" << endl;
	//	if (name != NULL) {
	//		delete name;
	//		name = NULL;
	//	}
	//}
	// 纯虚析构函数
	virtual ~Base() = 0;
	string* name;
};
Base::~Base(){
	cout << "Base的纯虚析构函数" << endl;
	if (name != NULL) {
		delete name;
		name = NULL;
	}
}
class Son :public Base {
public:
	Son(){
		cout << "Son的构造函数!" << endl;
	}
	~Son() {
		cout << "Son的析构函数!" << endl;
	}

};
void test() {
	Base* b = new Son;
	delete b;
}

int main() {
	test();
	system("pause");
	return 0;

}
Base的构造函数!
Son的构造函数!
Son的析构函数!
Base的纯虚析构函数
请按任意键继续. . .

实战案例
电脑主要组成部件为CPU(用于计算),显卡(用于显示),内存条(用于存储)
将每个零件封装出抽象基类,并且提供不同的厂商生产不同的零件,例救Intel厂商和Lenovo厂商创建电脑类提供让电脑工作的函敌,并且调用每个零件工作的接口
测试时组装三台不同的电脑进行工作

#include <iostream>
using namespace std;
// CPU抽象类
class CPU {
public:
	// 纯虚函数
	virtual void caculate() = 0;
};
// 显卡抽象类
class VideoCard {
public:
	// 纯虚函数
	virtual void display() = 0;
};
// 内存条抽象类
class Memory {
public:
	// 纯虚函数
	virtual void storage() = 0;
};
// Inter的零件
class InterCPU :public CPU {
public:
	void caculate() {
		cout << "Inter的CPU开始计算!" << endl;
	}
};
class InterVideoCard :public VideoCard {
public:
	void display() {
		cout << "Inter的显卡开始显示!" << endl;
	}
};
class InterMemory :public Memory {
public:
	void storage() {
		cout << "Inter的存储条开始存储!" << endl;
	}
};
// Lenovo的零件
class LenovoCPU :public CPU {
public:
	void caculate() {
		cout << "Lenovo的CPU开始计算!" << endl;
	}
};
class LenovoVideoCard :public VideoCard {
public:
	void display() {
		cout << "Lenovo的显卡开始显示!" << endl;
	}
};
class LenovoMemory :public Memory {
public:
	void storage() {
		cout << "Lenovo的存储条开始存储!" << endl;
	}
};
// 电脑类
class Computer {
public:
	Computer(CPU* c, VideoCard* v, Memory* m) {
		mc = c;
		mv = v;
		mm = m;
	}
	void dowork() {
		mc->caculate();
		mv->display();
		mm->storage();
	}
	virtual ~Computer() {
		//cout << "电脑的析构函数!" << endl;
		if (mc != NULL) {
			delete mc;
			mc = NULL;
		}
		if (mv != NULL) {
			delete mv;
			mv = NULL;
		}
		if (mm != NULL) {
			delete  mm;
			mm = NULL;
		}
	}
private:
	CPU * mc;
	VideoCard * mv;
	Memory* mm;
};

void start() {
	// 创建三台电脑
	cout << "第一台电脑:" << endl;
	Computer c1(new InterCPU, new InterVideoCard, new InterMemory);
	c1.dowork();
	cout << "第二台电脑:" << endl;
	Computer c2(new LenovoCPU, new LenovoVideoCard, new InterMemory);
	c2.dowork();
	cout << "第三台电脑:" << endl;
	Computer c3(new InterCPU, new InterVideoCard, new LenovoMemory);
	c3.dowork();
}
int main() {
	start();
	system("pause");
	return 0;

}
第一台电脑:
Inter的CPU开始计算!
Inter的显卡开始显示!
Inter的存储条开始存储!
第二台电脑:
Lenovo的CPU开始计算!
Lenovo的显卡开始显示!
Inter的存储条开始存储!
第三台电脑:
Inter的CPU开始计算!
Inter的显卡开始显示!
Lenovo的存储条开始存储!
请按任意键继续. . .

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

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

相关文章

ffmpeg命令增加headers参数解决http请求ts返回404 not found问题的解决方法:-headers、-an

最近项目上遇到一个问题&#xff0c;用ffmpeg请求录制一个m3u8的实时流成为mp4文件的时候&#xff0c;命令返回404错误&#xff1a; 但是有一个很奇怪的现象&#xff0c;就是ffmpeg请求不到的&#xff0c;VLC却能正常播放&#xff0c;对比一下抓包&#xff1a; 那么既然就差别…

leetcode17 电话号码的字母组合

方法1 if-else方法 if-else方法的思路及其简单粗暴&#xff0c;如下图所示&#xff0c;以数字234为例&#xff0c;数字2所对应的字母是abc&#xff0c;数字3所对应的是def&#xff0c;数字4所对应的是ghi&#xff0c;最后所产生的结果就类似于我们中学所学过的树状图一样&…

VUE指令(一)

vue会根据不同的指令&#xff0c;针对不同的标签实现不同的功能。指令是带有 v- 前缀的特殊标签属性。指令的职责是&#xff0c;当表达式的值改变时&#xff0c;将其产生的连带影响&#xff0c;响应式地作用于 DOM。 1、v-text&#xff1a;设置元素的文本内容&#xff0c;不会解…

LabVIEW在动态力传感器校准技术的创新应用

简介 动态力传感器校准装置集成了冲击法原理和自动化控制&#xff0c;实现精准、高效的传感器校验。LabVIEW的图形化界面提供简便操作和实时数据分析&#xff0c;显著提高了校准过程的准确度和效率。 01 系统设计和功能 动态力传感器在工业生产中发挥着重要作用&#xff0c;其…

基于SSM的驾校预约管理系统

基于SSM的驾校预约管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 详情 管理员界面 摘要 随着社会的不断发展&#xff0c;驾驶技能的需求逐渐增…

MySQL入门:DCL数据控制语言(管理用户,权限控制),MySQL函数(字符串,数值,日期,流程)

目录 1.DCL&#xff08;数据控制语言&#xff09;1.管理用户2.权限控制 2.函数1.字符串函数2.数值函数3.日期函数4.流程函数 1.DCL&#xff08;数据控制语言&#xff09; DCL英文全称是Data ControlLanguage(数据控制语言)&#xff0c;用来管理数据库用户、控制数据库的访问权限…

linux 内存

linux内存分类 按用途分 stack heap(brk,sbrk , mmap), 文件映射&#xff0c; bss&#xff0c; data , text, 还有page cache&#xff0c; slab&#xff08;kmalloc连续&#xff09;, vmalloc等内核深处的。 属性 进程OOM 对于进程来说&#xff0c;堆泄漏在死亡时是没问题 但…

轻松上手Linux文件操作:五种方法教你创建文件

轻松上手Linux文件操作&#xff1a;五种方法教你创建文件 一、引言二、使用touch命令创建文件三、使用文本编辑器创建文件四、使用echo命令创建文件五、使用cat命令创建文件六、使用重定向符号创建文件七、总结 一、引言 本文介绍五种在Linux系统中创建文件的方法&#xff0c;…

自制数据库空洞率清理工具-C版-03-EasyClean-V1.2(支持南大通用数据库Gbase8a)

目录 一、环境信息 二、简述 三、升级点 四、支持功能 五、空洞率 六、工具流程图 1、流程描述 2、注意点 &#xff08;1&#xff09;方法一 &#xff08;2&#xff09;方法二 七、清理空洞率流程图 八、安装包下载地址 九、参数介绍 1、命令模板 2、命令样例 3…

Jmeter接口自动化03-JMeter的常用核心组件

p03 高清B站视频链接 由于JMeter涉及的组件数目很多&#xff0c;据不完全统计至少有110个&#xff0c;而其实只需要掌握20%的组件就可以完成80%甚至更多的日常工作了&#xff0c;所以接下来我们重点剖析使用最频繁的核心组件&#xff0c;如下图所示。只需要优先掌握这10个左右…

IBM X3750 M4服务器主板故障全国协助处理

2023年12月31这天中午看到有位网络朋友加我&#xff0c;通过后该用户反馈说是有一台IBM System x3750 M4服务器有故障&#xff0c;现在无法开机。希望我们工程师协助他检测 分析 定位该故障问题原因和处理方案。 如上图所示&#xff1a;经过工程师与用户排查&#xff0c;发现该…

3D scanner with DLPC3478

https://www.bilibili.com/video/BV1vJ411J7ih?p3&vd_source109fb20ee1f39e5212cd7a443a0286c5 因数&#xff1a; 分别率波长pattern速度 DMD 与 DLPC匹配 3D scanner是结构光的概念走的 Internal pattern, 是DLPC内部提供图像给DMD External Pattern, 外部FPGA /MCU…

河南省农村合作医疗 及 社保缴费信息 查询方法

河南省农村合作医疗 及 社保缴费信息 查询方法 参考链接&#xff1a;河南城乡居民参保网上缴费及查询操作流程&#xff01; 一、河南省农村合作医疗&#xff0c;缴费信息查询方法 1、在支付宝或者微信中搜索 “河南税务” 公众号&#xff0c;并按步骤登陆&#xff1b; 2、在…

C桑(Cython)从入坑到入土(1)

Cython 概览 Cython 是一个将类似 Python 的代码文件编译为 C 代码的编译器。尽管如此&#xff0c;“Cython 不是 Python 到 C 的翻译器”。也就是说&#xff0c;它不会将完整的程序"转换为 C"------相反&#xff0c;结果会充分利用 Python 运行时环境。一种看待它…

Visual Studio中项目添加链接文件

这个需求在VS里面使用还真不多见&#xff0c;只是最近在做项目的版本编号的时候遇到一个头大的问题&#xff0c;我一个解决方案下面有几十个类库&#xff0c;再发布的时候这几十个类库的版本号必须要统一&#xff0c;之前我们都是在单个的AssemblyInfo.cs里面去改相关的信息&am…

CCF模拟题 202309-2 坐标变换(其二)

问题描述 试题编号&#xff1a; 202309-2 试题名称&#xff1a; 坐标变换&#xff08;其二&#xff09; 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 512.0MB 问题描述&#xff1a; 对于平面直角坐标系上的坐标 &#xff08;x,y&#xff09;&#xff0c;小 P 定义了如下两…

如何解决NAND系统性能问题?--NAND分类

一、故事引言 想象一下&#xff0c;你正在管理一座神奇的数据仓库&#xff0c;这个仓库没有沉重的门、旋转的磁盘和机械手臂&#xff0c;而是由一群训练有素的“数据小飞侠”组成。这些小飞侠们居住在一个叫做闪存芯片&#xff08;NAND Flash&#xff0c;本文主人公&#xff0…

【Linux】进程信号——进程信号的概念和介绍、产生信号、四种产生信号方式、阻塞信号、捕捉信号、阻塞和捕捉信号的函数

文章目录 进程信号1.进程信号的概念和介绍2.产生信号2.1通过终端按键产生信号2.2 调用系统函数向进程发信号2.3 由软件条件产生信号2.4硬件异常产生信号 3.阻塞信号3.1信号在内核中的表示3.2信号集操作函数3.3sigprocmask 4.捕捉信号4.1内核如何实现信号的捕捉4.2 sigaction 进…

Docker安装MySql详细步骤

1、新建挂载目录 首先进入安装mysql的目录&#xff0c;没有就自行创建 mkdir -p /usr/local/docker/mysql-docker cd /usr/local/docker/mysql-docker 接着挂载目录 # 选择自己的软件安装目录&#xff0c;新建挂载文件目录 mkdir -p data logs mysql-files conf # 赋予权限…

xcode安装及运行源码

抖音教学视频 目录 1、xcode 介绍 2、xcode 下载 3、xocde 运行ios源码 4、快捷键 1、xcode 介绍 Xcode 是运行在操作系统Mac OS X上的集成开发工具&#xff08;IDE&#xff09;&#xff0c;由Apple Inc开发。Xcode是开发 macOS 和 iOS 应用程序的最快捷的方式。Xcode 具有…