类 —— 封装、四类特殊成员函数、this指针、匿名对象、深浅拷贝问题

将同一类对象的所有属性都封装起来。
类中最基础的内容包括两部分,一个是属性、一个是行为
● 属性:表示一些特征项的数值,比如说:身高、体重、性别、肤色。这些属性都是名词。属性一般都以名词存在。属性的数值,也被称为“成员变量”。
● 行为:表示能执行的动作,能干什么?比方说:吃饭、睡觉、唱跳rap,篮球。打游戏。打架。这些行为一般通过函数实现,也被称为“成员函数”。行为一般以动词存在。
成员 = 成员变量+成员函数。

定义

class 类名
{
访问权限:
成员属性;
访问权限:
成员方法;
};

封装

封装指的是,将类的一些属性和细节隐藏,重新提供外部访问的接口。封装可以提升代码的安全性,并且可以让程序员更关注于上层架构而非内部细节。

访问权限:public、private、protected

public:共有的,类内、类外和子类中都可以访问
private:私有的,类内可以访问,类外和子类中都不能访问(类中的默认权限是私有权限
protected:受保护的,类内和子类中可以访问,类外不可以访问

类和结构体的区别

1、类的封装性比结构体更好,类中的默认权限是私有权限,结构体中默认权限是公有权限;
2、结构体默认是公有继承,类默认是私有继承;
3、C++中,类就是由结构体演变来的;
4、结构体一般用于实现某种数据结构,类一般用于描述一类对象的性质(属性、方法的封装);

对象的创建

C++中存在两种类型对象:
栈内存对象
对象所在的 {} 执行完毕后,自动被销毁。
堆内存对象
必须使用 new 关键字创建,使用指针保存。如果不使用 delete 关键字将其销毁,则堆内存对象会持续存在。

堆内存对象调用成员,使用 "->"。
栈内存对象调用成员,使用 "."。

💡 练习 1

定义一个长方形类,包含 私有属性:长、宽;
公有方法:设置长和宽,
定义一个 show 函数,获取长方形的长和宽;
输出长方形的面积和周长。

#include <iostream>
using namespace std;class rectangle
{
private:float width;float height;
public:void set(float new_width, float new_height);void show();float area();float perimeter();
};void rectangle::set(float new_width, float new_height)
{width = new_width;height = new_height;
}
void rectangle::show()
{cout << "Width: " << width << endl;cout << "Height: " << height << endl;
}
float rectangle::area()
{return width * height;
}
float rectangle::perimeter()
{return (width + height) * 2;
}int main()
{rectangle rec;float w, h;cout << "Input width and height:" << endl;cin >> w >> h;rec.set(w, h);rec.show();cout << "S = " << rec.area() << endl;cout << "C = " << rec.perimeter() << endl;return 0;
}

运行结果如下:
在这里插入图片描述

💡 练习 2

在 练习1 的基础上,设置新的函数,判断两个类对象是否完全相等(长 = 长,宽 = 宽)。

#include <iostream>using namespace std;class rectangle
{
private:float width;float height;
public:void set(float new_width, float new_height);
/*    void show();float area();float perimeter();	*/bool whether_same(rectangle &r1, rectangle &r2);	// 也可以定义为全局函数// 但需要额外定义获取长、宽的方法// float get_wid();// float get_hgt();
};void rectangle::set(float new_width, float new_height)
{width = new_width;height = new_height;
}
float rectangle::get_wid()
{return width;
}
float rectangle::get_hgt()
{return height;
}
bool rectangle::whether_same(rectangle &r1, rectangle &r2)	// 也可以定义为全局函数
{															// 但需要调用获取长、宽的方法return (r1.width == r2.width && r1.height == r2.height);// return (r1.get_wid() == r2.get_wid() && r1.get_hgt() == r2.get_hgt());
}int main()
{rectangle rec1, rec2, rec;float w1, h1, w2, h2;cout << "Input width and height twice:" << endl;cin >> w1 >> h1;cin >> w2 >> h2;rec1.set(w1, h1);rec2.set(w2, h2);if (rec.whether_same(rec1, rec2))		// 若定义为全局函数,则不需要利用对象 rec 调用cout << "Rectangle1 & rectangle2 are same." << endl;elsecout << "Rectangle1 & rectangle2 are different." << endl;return 0;
}

在这里插入图片描述
在这里插入图片描述

this 指针

每一个类中的非静态成员函数,都有一个 this 指针,指向调用者(谁调用 this 就指向谁)。
this 指针是一个特殊的指针,指向当前类对象的首地址只能在类内使用
成员函数(包括构造函数与析构函数)中都有 this 指针,this 指针指向的就是当前运行的成员函数所绑定的对象。

#include <iostream>
#include <string.h>using namespace std;
class Test
{
private:string name;
public:Test(string n){name = n;}void test_this(){cout << this << endl; }
};int main()
{Test t1("小明");cout << &t1 << endl; 		// 0x61fe84t1.test_this();				// 0x61fe84cout << "-----------" << endl;Test *t2 = new Test("张三");cout << t2 << endl; 		// 0x742698t2->test_this();    		// 0x742698delete t2;return 0;
}

原型:

类的类型 *const this; // 指针的指向不能修改

使用 this 指针的场合:

1、当形参和成员属性同名;

在这里插入图片描述

#include <iostream>using namespace std;class rectangle
{
private:float width;float height;
public:void set(float width, float height);void show();float area();float perimeter();	bool whether_same(rectangle &r1, rectangle &r2);	
};void rectangle::set(float width, float height)
{this->width = width;this->height = height;
}
void rectangle::show()
{cout << "Width: " << width << endl;cout << "Height: " << height << endl;
}
2、函数,需要返回自身的引用;

支持链式调用的成员函数特点:返回值是当前类的引用。
■ 返回值是当前类的引用。
return *this;

1)拷贝赋值函数
2)其他链式调用
#include <iostream>
#include <string.h>using namespace std;class Test
{
private:int val = 0;
public:Test &add(int i){val += i;   		// val = val + i;return *this; 		// this是一个指针,需要解引用返回对象的引用}int get_val(){return val;}
};int main()
{Test t1;t1.add(1);t1.add(2);t1.add(100);cout << t1.get_val() << endl; 							// 103// 链式调用Test t2;cout << t2.add(2).add(3).add(200).get_val() << endl;	// 205return 0;
}

类中的特殊成员函数

类中会默认提供一些特殊的成员函数:构造函数、析构函数、拷贝构造函数、拷贝赋值函数。

构造函数(支持函数重载、默认参数)

在实例化类对象时,系统默认调用无参构造函数。若自定义了构造函数,则系统将不提供构造函数。

类名()
{
// 函数体
}
------------------------------------------
类名(参数列表)
{
// 函数体
}

显示调用 & 隐式调用

显示调用:类名 对象名(实参列表);
隐式调用:类名 对象名 = {实参列表}; | 类名 对象名 = 实参;

建议使用显示调用,可以使用 explicit 关键字屏蔽隐式调用语法:

explicit 类名(参数列表)
{
// 构造函数
}

调用时机
类的嵌套:内层类先构造,外层类后构造;
类的继承:父类先调用构造,子类后调用构造

栈区:实例化类对象时(不初始化),调用无参构造函数
堆区:使用 new 申请空间时(不初始化),调用无参构造函数
在这里插入图片描述

初始化列表的机制

在这里插入图片描述
在这里插入图片描述

在函数体内部给成员属性赋值,是一个赋值的过程,不是初始化的过程。

在这里插入图片描述

类名(参数列表):成员1的属性(形参1的值), 成员2的属性(形参2的值), …

在这里插入图片描述

需要使用初始化列表的情况
1、形参和成员属性同名
2、类中有引用成员时,必须使用初始化列表

在这里插入图片描述

#include <iostream>
using namespace std;class rectangle
{
private:float width;float height;float &diagonal;
public:rectangle():diagonal(diagonal){cout << "A constructor without parameters." << endl;}// 构造函数可以被重载rectangle(float width, float height, float diagonal):width(width),height(height),diagonal(diagonal){cout << "A constructor with parameters." << endl;}
};int main()
{rectangle rec1;rectangle rec2(12, 5, 13);
//    rectangle rec3 = {12, 5, 13};       // 部分版本报错return 0;
}

3、类中有 const 修饰的成员时,必须使用初始化列表
在这里插入图片描述

#include <iostream>
using namespace std;class rectangle
{
private:float width;float height;const float diagonal;
public:rectangle():diagonal(diagonal){cout << "A constructor without parameters." << endl;}// 构造函数可以被重载rectangle(float width, float height, float diagonal):width(width),height(height),diagonal(diagonal){cout << "A constructor with parameters." << endl;}
};int main()
{rectangle rec1;rectangle rec2(12, 5, 13);
//    rectangle rec3 = {12, 5, 13};       // 部分版本报错return 0;
}
4、类中含有其他类的子对象时,必须使用初始化列表

如果内部类只有有参构造,需要在外部类的有参构造、无参构造的初始化列表中宏显性调用;
如果内部类存在无参构造,外部类可以不写无参构造的初始化列表。
在这里插入图片描述
在这里插入图片描述

#include <iostream>
using namespace std;class polygon
{string type;
public:// 注意:因为存在自定义的有参构造函数,系统不再提供无参构造函数polygon(string type){this->type = type;cout << "Inner constructor." << endl;}
};class rectangle
{
private:float width;float height;polygon p_type;
public:rectangle():p_type("a default value")				// 注意此行{cout << "A constructor without parameters." << endl;}// 构造函数可以被重载rectangle(float width, float height, string type):width(width),height(height), p_type(type){cout << "A constructor with parameters." << endl;}
};int main()
{rectangle rec1;rectangle rec2(12, 5, "rectangle");
//    rectangle rec3 = {12, 5, "rectangle"};       // 部分版本报错return 0;
}

在这里插入图片描述

#include <iostream>
using namespace std;class polygon
{string type;
public:// 注意:加上自定义的无参构造函数后,外部类可以不写无参构造的初始化列表。见 L27.polygon(){cout << "There's nothing." << endl;}polygon(string type){this->type = type;cout << "Inner constructor." << endl;}
};class rectangle
{
private:float width;float height;polygon p_type;
public:rectangle()//:p_type("a default value"){cout << "A constructor without parameters." << endl;}// 构造函数可以被重载rectangle(float width, float height, string type):width(width),height(height), p_type(type){cout << "A constructor with parameters." << endl;}
};int main()
{rectangle rec1;rectangle rec2(12, 5, "rectangle");
//    rectangle rec3 = {12, 5, "rectangle"};       // 部分版本报错return 0;
}

在这里插入图片描述

构造函数 v.s. 析构函数

在这里插入图片描述

析构函数(不支持重载)

在类对象空间消亡时,系统自动调用。

~类名()
{
// 函数体
}

调用时机(先构造的后析构,后构造的先析构)

栈区:类对象消亡时,系统自动调用
堆区:使用 delete 释放空间时,系统调用析构函数

#include <iostream>
using namespace std;class polygon
{string type;
public:polygon(){cout << "There's nothing." << endl;}~polygon(){cout << "Destructor of polygon." << endl;}
};class rectangle
{
private:float width;float height;polygon p_type;
public:rectangle(){cout << "A constructor without parameters." << endl;}~rectangle(){cout << "Destructor of rectangle." << endl;}
};int main()
{rectangle rec1;rectangle *p;p = new rectangle;delete p;return 0;
}

在这里插入图片描述

需要显性写出析构函数的情况(类指针成员指向堆区空间)

类中有指针成员,并且指针成员指向堆区空间。

#include <iostream>
using namespace std;class rectangle
{
private:float width;float height;int *ptr;
public:rectangle():ptr(new int)		// 保证指针成员 指向 堆区空间{cout << "A constructor without parameters." << endl;cout << "New address: " << ptr << endl;}~rectangle(){cout << "Delete address: " << ptr << endl;delete ptr;cout << "Destructor of rectangle." << endl;}
};int main()
{rectangle rec1;return 0;
}

在这里插入图片描述

#include <iostream>
using namespace std;class rectangle
{
private:float width;float height;int *ptr;
public:rectangle():ptr(new int)			// 保证指针成员 指向 堆区空间{cout << "A constructor without parameters." << endl;cout << "New address: " << ptr << endl;}rectangle(float width, float height, int ptr):width(width), height(height), ptr(new int(ptr)){									// 不能用 int *ptrcout << ptr << endl;cout << "A constructor with parameters." << endl;}~rectangle(){cout << "Delete address: " << ptr << endl;delete ptr;cout << "Destructor of rectangle." << endl;}
};int main()
{int num = 69;int *p = &num;rectangle rec1(12, 5, *p);return 0;
}

在这里插入图片描述
在这里插入图片描述

拷贝构造函数

利用 一个类对象 给另一个类对象初始化时,自动调用拷贝构造函数(浅拷贝)。
如果自定义了拷贝构造,则系统不再提供默认的拷贝构造。

类名 ( 被拷贝的同类对象的引用 )
{
// 函数体
}

浅拷贝构造(系统自动完成)
// 浅拷贝构造(系统自动完成)#include <iostream>
using namespace std;class rectangle
{
private:float width;float height;int *ptr;
public:void show();rectangle():ptr(new int)		// 保证指针成员 指向 堆区空间{cout << "A constructor without parameters." << endl;cout << "New address: " << ptr << endl;}rectangle(float width, float height, int ptr):width(width), height(height), ptr(new int(ptr)){cout << ptr << endl;cout << "A constructor with parameters." << endl;}~rectangle(){cout << "Delete address: " << ptr << endl;delete ptr;cout << "Destructor of rectangle." << endl;}
};void rectangle::show()
{cout << "Width: " << width << endl;cout << "Height: " << height << endl;cout << "Ptr = " << ptr << endl;
}int main()
{rectangle rec1(12, 5, 13);cout << "Show rec1: " << endl;rec1.show();rectangle rec2 = rec1;cout << "Show rec2: " << endl;rec2.show();return 0;
}

在这里插入图片描述

尝试手动添加拷贝构造函数
// 半成品(累了请忽略)#include <iostream>
using namespace std;class rectangle
{
private:float width;float height;int *ptr;
public:void show();rectangle():ptr(new int){cout << "A constructor without parameters." << endl;cout << "New address: " << ptr << endl;}rectangle(float width, float height, int ptr):width(width), height(height), ptr(new int(ptr)){cout << ptr << endl;cout << "A constructor with parameters." << endl;}~rectangle(){cout << "Delete address: " << ptr << endl;delete ptr;cout << "Destructor of rectangle." << endl;}rectangle(rectangle &other)						// 注意此行{this->width = other.width;this->height = other.height;this->ptr = other.ptr;cout << "Duplicate of rectangle. " << endl;}
};void rectangle::show()
{cout << "Width: " << width << endl;cout << "Height: " << height << endl;cout << "Ptr = " << ptr << endl;
}int main()
{rectangle rec1(12, 5, 13);cout << "Show rec1: " << endl;rec1.show();rectangle rec2 = rec1;cout << "Show rec2: " << endl;rec2.show();return 0;
}

在这里插入图片描述

深拷贝构造
// 深拷贝构造#include <iostream>
using namespace std;class rectangle
{
private:float width;float height;int *ptr;
public:void show();rectangle():ptr(new int){cout << "A constructor without parameters." << endl;cout << "New address: " << ptr << endl;}rectangle(float width, float height, int ptr):width(width), height(height), ptr(new int(ptr)){cout << ptr << endl;cout << "A constructor with parameters." << endl;}~rectangle(){cout << "Delete address: " << ptr << endl;delete ptr;cout << "Destructor of rectangle." << endl;}rectangle(rectangle &other):width(other.width), height(other.height), ptr(new int(*(other.ptr))){							// 使用同类其他对象的指针成员解引用后的值,给自己的指针成员的内容初始化
//        this->width = other.width;
//        this->height = other.height;
//        this->ptr = new int (*(other.ptr));			// 也可以,是赋值,不是初始化列表cout << "Duplicate of rectangle. " << endl;}
};void rectangle::show()
{cout << "Width: " << width << endl;cout << "Height: " << height << endl;cout << "Ptr = " << ptr << endl;
}int main()
{rectangle rec1(12, 5, 13);cout << "Show rec1: " << endl;rec1.show();rectangle rec2 = rec1;cout << "Show rec2: " << endl;rec2.show();return 0;
}

在这里插入图片描述

【思考】 深拷贝的代码是否存在隐患?

存在,new 开辟的空间无法释放,造成内存泄漏的问题。所以需要显性写出析构函数(见上面)。

调用时机(利用 一个类对象 给另一个类对象初始化)

1、使用已有的类对象,给新的类对象初始化
2、函数的参数是一个类对象时,也会调用拷贝构造函数
3、函数的返回值是一个类对象时,也会调用拷贝构造函数

#include <iostream>
using namespace std;class rectangle
{private:float width;float height;
public:void show();rectangle(){cout << "A constructor without parameters." << endl;}rectangle(float width, float height):width(width), height(height){cout << "A constructor with parameters." << endl;}rectangle(rectangle &other):width(other.width), height(other.height){cout << "Duplicate of rectangle. " << endl;}
};void rectangle::show()
{cout << "Width: " << width << endl;cout << "Height: " << height << endl;
}rectangle fun(rectangle s1)			// 应该这样写:rectangle &fun(rectangle &s1)
{return s1;
}int main()
{rectangle s(12, 5);fun(s).show();// rectangle s2(fun(s));        // 会报错,因为 fun(s) 的返回值是一个临时值,不能引用return 0;
}

在这里插入图片描述

在这里插入图片描述

深浅拷贝问题**

当类中有指针成员,会涉及到深浅拷贝问题。
默认的拷贝构造函数会导致两个对象的成员变量指向同一处。不符合面向对象的设计规范。这种现象被称为“浅拷贝”。
必须手动重写拷贝构造函数,使每次赋值都创建一个新的副本,从而每个对象单独持有自己的成员变量。这种方式就是“深拷贝”。

浅拷贝:两个(多个)对象的指针成员,指向同一片空间。
(不写拷贝构造函数或拷贝赋值函数,系统自动生成)
产生问题:同一片空间被两个不同的类对象占用,发生资源抢占。析构时会发生二次释放问题。

深拷贝:两个(多个)对象的指针成员,指向不同的空间,但保存的是同样的数据。
(手动书写拷贝构造函数或拷贝赋值函数)

在这里插入图片描述
在这里插入图片描述

● 在需求不受影响的前提下,可以直接通过屏蔽拷贝构造函数(私有化)来解决浅拷贝问题,但不建议如此。

拷贝赋值函数

使用 已有的类对象 给另外一个已有的类对象 赋值。系统默认提供一个拷贝赋值函数。
本质:赋值运算符的重载。

类名 &operator = (const 类名 &other)
{
// 函数体
}

浅拷贝赋值
// 浅拷贝赋值(默认缺省,系统自动完成)#include <iostream>
using namespace std;class rectangle
{
private:float width;float height;int *ptr;
public:void show();rectangle():ptr(new int){cout << "A constructor without parameters." << endl;cout << "New address: " << ptr << endl;}rectangle(float width, float height, int ptr):width(width), height(height), ptr(new int(ptr)){cout << ptr << endl;cout << "A constructor with parameters." << endl;}~rectangle(){cout << "Delete address: " << ptr << endl;delete ptr;cout << "Destructor of rectangle." << endl;}rectangle(rectangle &other):width(other.width), height(other.height), ptr(new int(*(other.ptr))){cout << "Duplicate of rectangle. " << endl;}
};void rectangle::show()
{cout << "Width: " << width << endl;cout << "Height: " << height << endl;cout << "Ptr = " << ptr << endl;
}int main()
{rectangle rec1(12, 5, 13);cout << "Show rec1: " << endl;rec1.show();rectangle rec2;rec2 = rec1;cout << "Show rec2: " << endl;rec2.show();return 0;
}

在这里插入图片描述

深拷贝赋值
// 深拷贝赋值#include <iostream>
using namespace std;class rectangle
{
private:float width;float height;int *ptr;
public:void show();rectangle():ptr(new int){cout << "A constructor without parameters." << endl;cout << "New address: " << ptr << endl;}rectangle(float width, float height, int ptr):width(width), height(height), ptr(new int(ptr)){cout << ptr << endl;cout << "A constructor with parameters." << endl;}~rectangle(){cout << "Delete address: " << ptr << endl;delete ptr;cout << "Destructor of rectangle." << endl;}rectangle(rectangle &other):width(other.width), height(other.height), ptr(new int(*(other.ptr))){cout << "Duplicate_constructor of rectangle. " << endl;}rectangle &operator = (const rectangle &other){this->width = other.width;// this->height = other.height;*ptr = *(other.ptr);cout << "Duplicate_operator of rectangle. " << endl;return *this;}
};void rectangle::show()
{cout << "Width: " << width << endl;cout << "Height: " << height << endl;cout << "Ptr = " << ptr << endl;
}int main()
{rectangle rec1(12, 5, 13);cout << "Show rec1: " << endl;rec1.show();rectangle rec2;rec2 = rec1;				// 注意:拷贝构造函数是定义对象的同时初始化,拷贝赋值函数是先定义对象再赋值cout << "Show rec2: " << endl;rec2.show();return 0;
}

在这里插入图片描述

对象的创建与销毁流程

#include <iostream>
using namespace std;class Value
{
private:string str;
public:Value(string str):str(str){cout << str << "构造函数" << endl;}~Value(){cout << str << "析构函数" << endl;}
};class Father
{
public:static Value s_value;Value val = Value("Father 成员变量");Father(){cout << "Father 构造函数被创建了"  << endl;}~Father(){cout << "Father 析构函数被调用了" << endl;}
};Value Father::s_value = Value("静态FatherValue被创建了");class Son:public Father
{
public :static Value s_value;Value val = Value("son 成员变量");Son(){cout << "Son 构造函数被创建了" << endl;}~Son(){cout << "Son 析构函数被调用了" <<endl;}};Value Son::s_value = Value("静态 SonValue被创建了");int main()
{cout << "主函数开始执行"<< endl;{Son s;cout << "对象执行中"<<endl;}									// Son s 的生命周期到此为止cout << "主函数结束了" << endl;return 0;
}

在这里插入图片描述

匿名对象

没有对象名,通过类名实例化出来的对象,生命周期短。 e.g. rectangle();

用作全局函数传参

// 方法一:class rectangle
{	// ......rectangle(rectangle &other):width(other.width), height(other.height), ptr(new int(*(other.ptr))){cout << "Duplicate_constructor of rectangle. " << endl;}// ......
}void func(rectangle &&rec)						// 注意此行
{// ......
}int main()
{func(rectangle());return 0;
}
// 方法二:class rectangle
{	// ......rectangle(const rectangle &other):width(other.width), height(other.height), ptr(new int(*(other.ptr))){cout << "Duplicate_constructor of rectangle. " << endl;}// ......
}void func(rectangle rec)
{// ......
}int main()
{func(rectangle());return 0;
}

临时使用类中的成员函数

rectangle().show();

给类对象的数组赋值

rectangle arr[2] = {rectangle(12, 5), rectangle(3, 4)};

给新的类对象赋值

rectangle recn(rectangle(6, 8));

💡 练习

定义一个 Person 类,包含私有属性:姓名、年龄、身高(通过指针实现)、性别(const成员)。
要求:写出类的构造函数,析构函数,拷贝构造函数 和 拷贝赋值函数。

#include <iostream>
using namespace std;class person
{
private:string name;int age;float *height;const string gender;
public:void show();person();person(string name, int age, float height, string gender);~person();person(person &other);person &operator = (const person &other);
};void person::show()
{cout << "Name: " << name << endl;cout << "Age: " << age << endl;cout << "Height: " << height << endl;cout << "Gender: " << gender << endl;
}
person::person():height(new float)
{cout << "A constructor without parameters." << endl;cout << "Height: " << height << endl;
}
person::person(string name, int age, float height, string gender):name(name), age(age), \height(new float(height)), gender(gender)
{
//  cout << height << endl;cout << "A constructor with parameters." << endl;
}
person::~person()
{cout << "Delete address: " << height << endl;delete height;cout << "Destructor of person." << endl;
}
person::person(person &other):name(other.name), age(other.age), \height(new float(*(other.height))), gender(other.gender)
{cout << "Duplicate_constructor of person. " << endl;
}
person &person::operator = (const person &other)
{this->name = other.name;this->age = other.age;*height = *(other.height);				// *(this->height) = *(other.height);string *p = (string *)&this->gender;*p = other.gender;cout << "Duplicate_operator of person. " << endl;return *this;
}int main()
{person per1("He Yanwei", 23, 180, "man");cout << "Show per1: " << endl;per1.show();person per2 = per1;cout << "Show per2: " << endl;per2.show();person per3;per3 = per1;cout << "Show per3: " << endl;per3.show();return 0;
}

在这里插入图片描述

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

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

相关文章

算法基础之食物链

食物链 核心思想&#xff1a;带权并查集 用距根节点和距离表示与根节点的关系 求距离 #include<iostream>using namespace std;const int N50010;int n,m;int p[N],d[N];//找到祖宗节点(路径压缩) 并求出对应距离int find(int x){if(p[x]!x){int up[x]; //保存旧父节点…

如何使用 Java 在Excel中创建下拉列表

下拉列表&#xff08;下拉框&#xff09;可以确保用户仅从预先给定的选项中进行选择&#xff0c;这样不仅能减少数据输入错误&#xff0c;还能节省时间提高效率。在MS Excel中&#xff0c;我们可以通过 “数据验证” 提供的选项来创建下拉列表&#xff0c;但如果要在Java程序中…

mysql账户密码获取

数据库安装目录 MySQL\data\mysql 里面的user.MYD文件&#xff0c;需要编译查看 数据库里的user表 库下面的user表拿到后&#xff0c;直接解密密码即可 网站配置文件 conn、config、data、sql、common 、inc这些文件 比如pikachu\inc目录下的config.inc.php文件的内容会显示…

速通CSAPP(一)计算机系统漫游入门

CSAPP学习 前言 一门经典的计组课程&#xff0c;我却到了大四才学。 anyway&#xff0c;何时都不会晚。 博主参考的教程&#xff1a;本电子书信息 - 深入理解计算机系统&#xff08;CSAPP&#xff09; (gitbook.io)&#xff0c;非常感谢作者的整理。 诚然去看英文版可以学…

【开源】基于Vue和SpringBoot的木马文件检测系统

项目编号&#xff1a; S 041 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S041&#xff0c;文末获取源码。} 项目编号&#xff1a;S041&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 木马分类模块2.3 木…

软著项目推荐 深度学习中文汉字识别

文章目录 0 前言1 数据集合2 网络构建3 模型训练4 模型性能评估5 文字预测6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习中文汉字识别 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xf…

【Vue】Linux 运行 npm run serve 报错 vue-cli-service: Permission denied

问题描述 在Linux系统上运行npm run serve命令时&#xff0c;控制台报错&#xff1a; sudo npm run serve project50.1.0 serve vue-cli-service serve sh: 1: vue-cli-service: Permission denied错误截图如下&#xff1a; 原因分析 该错误是由于vue-cli-service文件权限不…

线性转换函数S_RTR(SCL和ST代码)

模拟量转换函数S_ITR详细公式和算法源代码请查看下面文章链接: PLC模拟量输入 模拟量转换FC S_ITR_博途模拟量转换程序_RXXW_Dor的博客-CSDN博客文章浏览阅读5.4k次,点赞4次,收藏7次。模拟量采集、工业现场应用特别广泛、大部分传感器的测量值和输出信号都是线型关系,所以…

Rocky Linux 9.3 为 PowerPC 64 位带回云和容器镜像

RHEL 克隆版 Rocky Linux 9.3 今天发布了&#xff0c;作为红帽企业 Linux 发行版 CentOS Stream 和 Red Hat Enterprise Linux 的免费替代版本&#xff0c;现在可供下载。 Rocky Linux 9.3 是在 Rocky Linux 9.2 发布 6 个月之后发布的&#xff0c;它带回了 PowerPC 64 位 Lit…

4D雷达目标检测跟踪算法设计

1.算法流程 4D雷达点云跟踪处理沿用3D毫米波雷达的处理流程&#xff0c;如下图&#xff1a; 从接收到点云开始&#xff0c;先对点云做标定、坐标转换、噪点剔除、动静分离&#xff0c;再分别对动态目标和静态目标做聚类&#xff0c;然后根据聚类结果做目标的特征分析和检测等&a…

leetcode42接雨水问题

接雨水 题目描述 题目分析 核心思想&#xff1a; 代码 java版本&#xff1a; package com.pxx.leetcode.trapRainWaterDoublePoniter;public class Solution1 {public int trap(int[] height) {if (height.length 0) {return 0;}int n height.length;int left 0;int righ…

LabVIEWL实现鸟巢等大型结构健康监测

LabVIEWL实现鸟巢等大型结构健康监测 管理国家地震防备和减灾的政府机构中国地震局(CEA)选择了七座新建的巨型结构作为结构健康监测(SHM)技术的测试台。这些标志性建筑包括北京2008年夏季奥运会场馆&#xff08;包括北京国家体育场和北京国家游泳中心&#xff09;、上海104层的…

Eureka简单使用做微服务模块之间动态请求

创建一个eureka模块,引入eureka 为启动项加上EnableEurekaServer注解 配置信息 orderService和userService的操作是一样的 这里以orderService为例: 引入eureka客户端 加上 LoadBalanced注解 配置 orderService和userService都配置好了之后 启动 这样我们在http://localhos…

Python实现FA萤火虫优化算法优化循环神经网络分类模型(LSTM分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 萤火虫算法&#xff08;Fire-fly algorithm&#xff0c;FA&#xff09;由剑桥大学Yang于2009年提出 , …

【读懂AUTOSAR】DoIP模块(1)-- 使用场景和链接的建立规范

引子 --什么是?为什么使用DoIP? DoIP就是通过IP进行诊断的意思(Diagnostic Over IP)。我们熟悉的诊断都是通过CAN总线的啊,为什么要通过IP?IP是什么? IP就是Internet Protocol,就是”互联网协议“啦! 那DoIP就是通过互联网进行的诊断喽,也可以叫做“基于以太网的诊…

单片机学习11——矩阵键盘

矩阵键盘&#xff1a; 这个矩阵键盘可以接到P0、P1、P2、P3都是可以的。 使用矩阵键盘是能节省单片机的IO口。 P3.0 P3.1 P3.2 P3.3 称之为行号。 P3.4 P3.5 P3.6 P3.7 称之为列号。 矩阵键盘检测原理&#xff1a; 1、检查是否有键按下&#xff1b; 2、键的抖动处理&#xf…

阿里云服务器购买价格,云服务器与轻量应用服务器最新购买活动价格汇总

阿里云服务器租用价格是多少&#xff1f;不同时期阿里云服务器的租用价格不同&#xff0c;目前阿里云轻量应用服务器与云服务器优惠价格也有所变化&#xff0c;目前轻量应用服务器还是87元1年起&#xff0c;经济型e实例云服务器99元1年起&#xff0c;通用算力型u1云服务器643.6…

Flink CDC -Sqlserver to Sqlserver java 模版编写

1.基本环境 <flink.version>1.17.0</flink.version> 2. 类文件 package com.flink.tablesql;import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.apache.flink.streaming.api.environment.StreamExecutionEnviro…

护眼灯值不值得买?国AA级别标准的护眼台灯推荐

在中国&#xff0c;近视人口占全国总人数的30%左右。中全国患近视眼的总数达到3.6亿。城市近视人口的近视率达到33%。其中&#xff0c;大学生的近视率是最高的&#xff0c;达到了75&#xff05;左右。中学生的近视率大约为50&#xff05;。在校佩戴眼镜的小学生比例为30&#x…

开始使用Spring Boot Admin吧-使用Nacos注册SBA

什么是 Spring Boot Admin&#xff08;SBA&#xff09;? Spring Boot Admin 是 codecentric 公司开发的一款开源社区项目&#xff0c;目标是让用户更方便的管理以及监控 Spring Boot 应用。 应用可以通过我们的Spring Boot Admin客户端&#xff08;通过HTTP的方式&#xff0…