【C++笔记】类和对象的深入理解(三)

news2024/9/20 23:15:41

【C++笔记】类和对象的深入理解(三)

🔥个人主页大白的编程日记

🔥专栏C++笔记


文章目录

  • 【C++笔记】类和对象的深入理解(三)
    • 前言
    • 一.日期类的实现
      • 1.1声明和定义分离
      • 1.2日期类+=整数
      • 1.3日期类+整数
      • 1.4日期类-=整数
      • 1.5日期类-日期
      • 1.6复用对比
      • 1.7日期类==日期类
      • 1.8日期类<日期类
      • 1.9比较复用
      • 1.10前置和后置
      • 1.11日期类-日期类
      • 1.12日期类IO
    • 二.取地址运算符重载
      • 2.1const成员函数
      • 2.2取地址运算符重载
    • 三.再探构造函数
    • 四.类型转换
    • 五.static成员
    • 六.友元
    • 七.内部类
    • 八.匿名对象
    • 后言

前言

哈喽,各位小伙伴大家好!上期我们讲了类和对象的更深入的内容。今天我们就给类和对象收尾。话不多说,咱们进入正题!向大厂冲锋!

一.日期类的实现

为了加深我们前面对类和对象的理解。我们现在来试着手搓一个日期类。

1.1声明和定义分离

我们想让.h放函数的声明。.cpp放函数的定义。

#pragma once

#include<iostream>
using namespace std;
#include<assert.h>

class Date
{
	friend istream& operator>>(istream& in, Date& d);
	friend ostream& operator<<(ostream& out, const Date& d);//友元声明
public:
	Date(int year ,int month ,int day );
	void Print();

	// Ĭinline
	int GetMonthDay(int year, int month)
	{
		assert(month > 0 && month < 13);
		static int monthDayArray[13] = { -1, 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 };

		if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
		{
			return 29;
		}

		return monthDayArray[month];
	}
	int GetYear();
	int GetMonth();
	int GetDay();
	bool operator<(const Date& d) const;
	bool operator<=(const Date& d) const;
	bool operator>(const Date& d) const;
	bool operator>=(const Date& d) const;
	bool operator==(const Date& d) const;
	bool operator!=(const Date& d) const;
	bool CheckDate();
	Date operator+(int day) const;
	Date& operator+=(int day);
	Date operator++(int);//后置
	Date& operator++();//前置
	Date operator--(int);//后置
	Date& operator--();//前置
	Date& operator-=(int day);
	Date operator-(int day) const;
	int operator-(const Date& d) const;
private:
	int _year;
	int _month;
	int _day;
};
istream& operator>>(istream& in,  Date& d);
ostream& operator<<(ostream& out, const Date& d);

我们日期类主要实现他的比较和日期类之间的相互运算。

1.2日期类+=整数

这里我们的思路是先将整数加到天数上。然后如果天数不超过当月天数。直接返回即可。否则说明日期比当月的所有日期都大。则向下月借位。天数减去当月天数之和,以此类推知道天数不超过当月的最大天数位置。如果12借位则年份+1,月份改为1即可。

int GetMonthDay(int year, int month)
{
	assert(month > 0 && month < 13);
	static int monthDayArray[13] = { -1, 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 };

	if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
	{
		return 29;
	}
	return monthDayArray[month];
}
Date& Date::operator+=(int day)
{
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		_month++;
		if (_month == 13)
		{
			_year++;
			_month = 1;
		}
	}
	return *this;
}

1.3日期类+整数

现在我们实现日期类+整数,也就是不改变日期类。返回日期类+=整数的结果。那我们可以复用日期类+=整数的逻辑。为了不修改日期类。我们对日期类拷贝一份tmp。让tmp进行+=的逻辑这样改变就不会日期类。

Date Date::operator+(int day) const
{
	Date tmp=*this;
	tmp +=day;
	return tmp;
}

1.4日期类-=整数

这里思路和我们前面实现+的思路一样。都是通过借位的思想。我们向当天数-day。
然后当天数!>0时,向上一个月借位,天数+=上个月的天数(注意是上个月的,因为当月的天数已经被减过了)。如果是1月的话,借去年12月的天数。让月份=12然后年份–。

Date& Date::operator-=(int day)
{
	_day -= day;
	while (_day <= 0)
	{
		if (_month == 1)
		{
			_month = 12;
			_day += GetMonthDay(--_year, _month);
		}
		else
		{
			_day += GetMonthDay(_year, --_month);
		}
	}
	return *this;
}

1.5日期类-日期

日期类-日期我们就复用-=即可。

Date Date::operator-(int day) const
{
	Date tmp=*this;
	tmp -= day;
	return tmp;
}

1.6复用对比

在这里插入图片描述

1.7日期类==日期类

判断两个日期类很简单。我们只需要判断是否他们的年月日都相等即可。

bool Date::operator==(const Date& d) const
{
	if (_year == d._year && _month == d._month && _day == d._day)
	{
		return true;
	}
	else
	{
		return false;
	}
}

1.8日期类<日期类

判断两个日期类<。
先比较年。
<返回true。
==继续比较月。月<返回true。 ==返回比较天。
剩下的情况都是false的情况。直接返回false.

bool Date::operator<(const Date& d) const
{
	if (_year < d._year)//比较年
	{
		return true;
	}
	else if (_year == d._year)//年相等
	{
		if (_month < d._month)//判断月
		{
			return true;
		}
		else if (_month == d._month)//月相等
		{
			return _day < d._day; //判断天
		}
	}
	return false;//年不相等
}

1.9比较复用

剩下的我们通过前面实现的<和==复用即可。

bool Date::operator!=(const Date& d) const
{
	return !(*this == d);
}
bool Date::operator<=(const Date& d) const
{
	return *this < d || *this == d;
}
bool Date::operator>(const Date& d) const
{
	return !(*this < d)&&!(*this==d);
}
bool Date::operator>=(const Date& d) const
{
	return !(*this < d);
}

1.10前置和后置

前置我们拷贝一份*this,在复用+=或-=即可。

Date Date::operator++(int)
{
	Date tmp = *this;
	*this += 1;
	return tmp;
}
Date& Date::operator++()
{
	*this += 1;
	return *this;
}
Date Date::operator--(int)
{
	Date tmp=*this;
	*this-= 1;
	return tmp;
}
Date& Date::operator--()
{
	*this -= 1;
	return *this;
}

1.11日期类-日期类

两个日期类相减得出他们之间相差的天数。
我们的思路就是直接让小的天数一直相加,直到相加到小的日期和大的日期相等即可。每次日期++就用一个变量记录天数即可。

int Date::operator-(const Date& d) const
{
	int sum = 0;
	int flag = 1;
	Date max, min;
	max = *this;
	min = d;
	if (*this < d)//假设法
	{
		swap(max, min);
		flag = -1;
	}
	while (min!=max)
	{
		sum++; 
		min++;
	}
	sum *=flag;
	return sum;
}

1.12日期类IO

因为类的成员函数默认*this抢占了第一个位置。和我们平时的写法不一样。所以我们把日期类的输出和输出放在类外面。那放在类外面我们如何访问类的成员变量呢?那我们就可以加一个友元函数声明。

istream& operator>>(istream& in, Date& d)
{
	cout<<"请依次输入年月日:"<<endl;
	in >>d._year>> d._month >> d._day;
	return in;
}
ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year <<"年" << d._month<<"月" << d._day<<"日";
	return out;
}

为了实现连续输入或输出。我们需要返回istrem或ostrem对象。

同时注意流对象不支持拷贝。所以istrem或ostrem必须用引用。

二.取地址运算符重载

2.1const成员函数

  • 定义
    将const修饰的成员函数称之为const成员函数,const修饰成员函数放到成员函数参数列表的后面。

  • const修饰
    const实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。const 修饰Date类的Print成员函数,Print隐含的this指针由 Date* const this 变为const Date* const this。

    不写加const。

加上const。

同时非const成员也可以调用const成员函数。因为权限可以缩小。所以加上const可以防止我们的程序不小心篡改(原本不应该修改却不小心修改会报错),同时也让我们的的成员函数传参更宽泛,const成员也可以调用。所以能加尽加。

2.2取地址运算符重载

取地址运算符重载分为普通取地址运算符重载和const取地址运算符重载,⼀般这两个函数编译器自动生成的就可以够我们⽤了,不需要去显示实现。除非⼀些很特殊的场景,比如我们不想让别⼈取到当前类对象的地址,就可以自己实现⼀份,胡乱返回⼀个地址。

class Date
{
public:
	Date* operator&()
	{
		return this;
		// return nullptr;
	}
	const Date* operator&()const
	{
		return this;
		// return nullptr;
	}
private:
	int _year; // 年
	int _month; // ⽉
	int _day; // ⽇
};

一般这两个成员函数都不需要我们显示的写。因为他们两个是默认成员函数。

按理说我们只写const成员函数即可。因为不论是const成员还是非const成员都可以调用。但是const成员调用返回的是const this*。所以还需要写两份。并且编译器调用时会调用最匹配的。

三.再探构造函数

  • 初始化列表
    之前我们实现构造函数时,初始化成员变量主要使用函数体内赋值,构造函数初始化还有⼀种方式,就是初始化列表,初始化列表的使用方式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成员列表,每个"成员变量"后面跟⼀个放在括号中的初始值或表达式。

大概形式如下:

 Date(int& x, int year = 1, int month = 1, int day = 1)
 :_year(year)
 ,_month(month)
 ,_day(day)
 ,_t(12)
 ,_ref(x)
 ,_n(1)
 {
 // error C2512: “Time”: 没有合适的默认构造函数可⽤
// error C2530 : “Date::_ref” : 必须初始化引⽤
// error C2789 : “Date::_n” : 必须初始化常量限定类型的对象 
}
  • 定义的位置
    每个成员变量在初始化列表中只能出现⼀次,语法理解上初始化列表可以认为是每个成员变量定义初始化的地方。因为初始化列表是定义的地方所以,只能初始化一次。否则就会变成多次定义。

  • 定义初始化
    引用成员变量,const成员变量,没有默认构造的类类型变量,必须放在初始化列表位置进行初始化,否则会编译报错。

class Time
{
public:
	Time(int hour=0)
		:_hour(hour)
	{
		cout << "Time()" << endl;
	}
private:
	int _hour;
};
class Date
{
public:
	Date(int& x,int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
		,a(1)
		,_ref(x)//成员定义
	{
		// error C2512: “Time”: 没有合适的默认构造函数可⽤
		// error C2530 : “Date::_ref” : 必须初始化引⽤
		// error C2789 : “Date::_n” : 必须初始化常量限定类型的对象
	}
	void Print() const
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	//声明
	int _year;
	int _month;
	int _day; int main();
	int& _ref;
	const int a;
	Time _t;
};

引用成员变量,const成员变量必须在初始化列表初始化。因为他们必须在定义的地方初始化。

没有默认构造的类类型也必须在初始化列表初始化,因为他必须手动传参调用构造函数。
那初始化列表和函数体内赋值可以混着用吗?
可以,因为有些场景必须混着用。

Date(int& x,int year = 1, int month = 1, int day = 1)
	:_year(year)
	, _month(month)
	, _day(day)
	,a(1)
	,_ref(x)
	,_ptr((int*)malloc(size(int)//成员定义
{
	if (_ptr == nullptr)
	{
		perror(malloc fail!);
	}
}

例如有个指针,我们malloc以后需要检查是否失败。那就必须在函数体内检查。

  • 缺省值
    C++11支持在成员变量声明的位置给缺省值,这个缺省值主要是给没有显示在初始化列表初始化的成员使用的。
private:
	//声明
	int _year=1;
	int _month=1;
	int _day=1; 
	int* _ptr=((int*)malloc(sizeof(int)));

在声明的位置给一个缺省值。
在这里插入图片描述

  • 总结
    尽量使用初始化列表初始化,因为那些你不在初始化列表初始化的成员也会走初始化列表,如果这个成员在声明位置给了缺省值,初始化列表会用这个缺省值初始化。如果你没有给缺省值,对于没有显⽰在初始化列表初始化的内置类型成员是否初始化取决于编译器,C++并没有规定。对于没有显示在初始化列表初始化的⾃定义类型成员会调⽤这个成员类型的默认构造函数,如果没有默认构造会编译错误。
    所以初始化列表能写尽写,因为就算你不写他也会走初始化列表。

  • 初始化顺序
    初始化列表中按照成员变量在类中声明顺序进行初始化,跟成员在初始化列表出现的的先后顺序无关。建议声明顺序和初始化列表顺序保持⼀致。

大家看一下这道题选什么。

可能很多同学都会觉得选A。但实际不是这样的。因为初始化列表初始化的顺序是声明的顺序。

声明是顺序是他们在内存存放的顺序。初始化是按照内存中的顺序初始化。

四.类型转换

class A
{
public:
	//构造函数explicit就不再⽀持隐式类型转换
	// explicit A(int a1)
	A(int a1)
		:_a1(a1)
	{}
	//explicit A(int a1, int a2)
	A(int a1, int a2)
		:_a1(a1)
		, _a2(a2)
	{}
	void Print()
	{
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a1 = 1;
	int _a2 = 2;
};
int main()
{
	// 1构造⼀个A的临时对象,再⽤这个临时对象拷⻉构造aa3
	//编译器遇到连续构造+拷⻉构造->优化为直接构造
    A aa1 = 1;
	aa1.Print();
	const A& aa2 = 1;
	// C++11之后才⽀持多参数转化
    A aa3 = { 2,2 };
	return 0;
}
  • 隐式类型转化
    C++支持内置类型隐式类型转换为类类型对象,需要有相关内置类型为参数的构造函数。

    这里我们可以验证一下。

这里报错是为啥?
因为隐式类型转化生成是临时对象,临时对象具有常性。所以要加上const引用。

那隐式类型转化有什么用?

class Stack
{
public:
	void Push(const A& aa)
	{

	}
private:
	int top;
};
int main()
{
	Stack s;
	A aa = 1;
	s.Push(aa);
	s.Push(1);
	return 0;
}


可以发现隐式类型转化可以让我们写代码更加方便简洁。

  • explicit
    如果不想发生隐式类型转化, 构造函数前面加explicit就不再支持隐式类型转换。

五.static成员

  • 静态成员变量
    用static修饰的成员变量,称之为静态成员变量,静态成员变量⼀定要在类外进行初始化。
  • 共享
    静态成员变量为所有类对象所共享,不属于某个具体的对象,不存在对象中,存放在静态区。

  • 静态成员函数
    用static修饰的成员函数,称之为静态成员函数,静态成员函数没有this指针。

  • 访问权限
    静态成员函数中可以访问其他的静态成员,但是不能访问非静态的,因为没有this指针。非静态的成员函数,可以访问任意的静态成员变量和静态成员函数。

  • 指定类域
    突破类域就可以访问静态成员,可以通过类名::静态成员或者对象.静态成员来访问静态成员变量和静态成员函数。

  • 访问限定符
    静态成员也是类的成员,受public、protected、private访问限定符的限制。

  • 缺省值
    静态成员变量不能在声明位置给缺省值初始化,因为缺省值是个构造函数初始化列表的,静态成员变量不属于某个对象,不走构造函数初始化列表。

  • 练习一
    题目:求1+2+3…+n

这道题目把常规的方法都限制了。但是这道题可以用我们的静态成员解决。
这道题主要修饰构造出循环这个条件。所以我们可以用一个类数组来构造这个条件。
定义一个n大小的类数组。那就会调用n次构造。我们只需要定义两个静态成员。然后每次构造把当前的值累加即可。

class Sum {
  public:
    Sum() {
        _ret += _i;
        ++_i;
    }
    static int GetRet() {
        return _ret;
    }
  private:
    static int _i;
    static int _ret;
};
int Sum::_i = 1;
int Sum::_ret = 0;
class Solution {
  public:
    int Sum_Solution(int n) {
        //变⻓数组
        Sum arr[n];
        return Sum::GetRet();
    }
};

  • 练习二
C c;
int main()
{
	A a;
	B b;
	static D d;
	return 0;
}


六.友元

  • 定义
    友元提供了⼀种突破类访问限定符封装的方式,友元分为:友元函数和友元类,在函数声明或者类声明的前面加friend,并且把友元声明放到⼀个类的里面。
class A
{
	// 友元声明
    friend void func(const A& aa, const B& bb);
private:
	int _a1 = 1;
	int _a2 = 2;
};
void func(const A& aa, const B& bb)
 {
   cout << aa._a1 << endl;
   cout << bb._b1 << endl;
 }

例如这里func是A的好朋友,func就可以访问A的成员。

  • 声明
    外部友元函数可访问类的私有和保护成员,友元函数仅仅是⼀种声明,他不是类的成员函数。

  • 声明位置
    友元函数可以在类定义的任何地方声明,不受类访问限定符限制。

  • 多个友元
    ⼀个函数可以是多个类的友元函数。

class A
{
	// 友元声明
    friend void func(const A& aa, const B& bb);
private:
	int _a1 = 1;
	int _a2 = 2;
};
class B
{
	// 友元声明
    friend void func(const A& aa, const B& bb);
private:
	int _b1 = 3;
	int _b2 = 4;
};

func既是A的友元又是B的友元。

  • 友元类
    友元类中的成员函数都可以是另⼀个类的友元函数,都可以访问另⼀个类中的私有和保护成员
class A
{
	// 友元声明
    friend class B;
private:
	int _a1 = 1;
	int _a2 = 2;
};
class B
{
public:
	void func1(const A& aa)
	{
		cout << aa._a1 << endl;
		cout << _b1 << endl;
	}
	void func2(const A& aa)
	{
		cout << aa._a2 << endl;
		cout << _b2 << endl;
	}
private:
	int _b1 = 3;
	int _b2 = 4;
};
int main()
{
	A aa;
	B bb;
	bb.func1(aa);
	bb.func1(aa);
	return 0;
}

B是A的友元类。B的所有成员函数都可以访问A的成员变量。

  • 单向性
    友元类的关系是单向的,不具有交换性,比如A类是B类的友元,但是B类不是A类的友元。

  • 传递性
    友元类关系不能传递,如果A是B的友元,B是C的友元,但是A不是C的友元。

  • 使用
    有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

七.内部类

  • 定义
    如果⼀个类定义在另⼀个类的内部,这个内部类就叫做内部类。内部类是⼀个独立的类,跟定义在全局相比,他只是受外部类类域限制和访问限定符限制,所以外部类定义的对象中不包含内部类。
class A
{
private:
	static int _k;
	int _h = 1;
public:
	class B // B默认就是A的友元
	{
	public:
        void foo(const A& a)
        {
            cout << _k << endl; //OK
            cout << a._h << endl; //OK
        }
     private:
         int _b;
    };
};
int A::_k = 1;
int main()
{
    cout << sizeof(A) << endl;
    A::B b;
    A aa;
    b.foo(aa);
}


所以刚刚OJ的代码也可以改成内部类

class Solution {
    // 内部类
    class Sum
    {
    public:
        Sum()
        {
            _ret += _i;
            ++_i;
        }
    };
    static int _i;
    static int _ret;
 public:
    int Sum_Solution(int n) {
        // 变⻓数组
        Sum arr[n];
        return _ret;
    }
  • 默认友元
    内部类默认是外部类的友元类。
  • 封装
    内部类本质也是⼀种封装,当A类跟B类紧密关联,A类实现出来主要就是给B类使用,那么可以考虑把A类设计为B的内部类,如果放到private/protected位置,那么A类就是B类的专属内部类,其他地方都用不了。

八.匿名对象

  • 定义
    用类型(实参)定义出来的对象叫做匿名对象,相比之前我们定义的类型对象名(实参)定义出来的叫有名对象。

匿名对象让我们写代码更方便。

  • 生命周期
    匿名对象的生命周期只在当前⼀行,⼀般临时定义⼀个对象当前用⼀下即可,就可以定义匿名对象。

    可以看到未打印1之前,A就析构了。因为匿名对象声明周期只在当前行。

后言

这就是类和对象的深入理解。今天讲了很多内容。大家自己好好消化。感谢各位的耐心垂阅!咱们下期见!拜拜~

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

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

相关文章

并发安全与锁

总述 这篇文章&#xff0c;我想谈一谈自己对于并发变成的理解与学习。主要涉及以下三个部分&#xff1a;goroutine&#xff0c;channel以及lock 临界区 首先&#xff0c;要明确下面两组概念 并发和并行 并行&#xff1a;指几个程序每时每刻都同时进行 并发&#xff1a;指…

lnmp - 登录技术方案设计与实现

概述 登录功能是对于每个动态系统来说都是非常基础的功能&#xff0c;用以区别用户身份、和对应的权限和信息&#xff0c;设计出一套安全的登录方案尤为重要&#xff0c;接下来我介绍一下常见的认证机制的登录设计方案。 方案设计 HTTP 是一种无状态的协议&#xff0c;客户端…

iOS - TestFlight使用

做的项目需要给外部人员演示&#xff0c;但是不方便获取对方设备的UDID&#xff0c;于是采用TestFlight 的方式邀请外部测试人员的方式给对方安装测试App&#xff0c;如果方便获取对方设备的UDID&#xff0c;可以使用蒲公英 1.在Xcode中Archive完成后上传App Store Connect之前…

浙大上交联合阿里腾讯,共同构建医学AI领域的顶尖科研+商业团队|个人观点·24-09-17

小罗碎碎念 昨晚锻炼时&#xff0c;我想着是时候对推文的内容做一些改进了——既能通过写推文来锻炼自己写paper的能力&#xff0c;也希望凭借自己一点微弱的影响力&#xff0c;去带动更多的人加入医学AI的队伍中。 这一期推文系统且深度的分析一下&#xff0c;国内哪些学者在医…

Linux基础开发环境(git的使用)

1.账号注册 git 只是一个工具&#xff0c;要想实现便捷的代码管理&#xff0c;就需要借助第三方平台进行操作&#xff0c;当然第三平台也是基于git 开发的 github 与 gitee 代码托管平台有很多&#xff0c;这里我们首选 Github &#xff0c;理由很简单&#xff0c;全球开发者…

算法题之回文子串

回文子串 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 示例 1&#xff1a; 输入&#xff1a;s "abc" 输出&#xff1a;3 解释…

C++ 带约束的Ceres形状拟合

C 带约束的Ceres形状拟合 一、Ceres Solver1.定义问题2. 添加残差AddResidualBlockAutoDiffCostFunction 3. 配置求解器4. 求解5. 检查结果 二、基于Ceres的最佳拟合残差结构体拟合主函数 三、带约束的Ceres拟合残差设计拟合区间限定 四、拟合结果bestminmax 五、完整代码 对Ce…

RocksDB系列一:基本概念

0 引言 RocksDB 是 Facebook 基于 Google 的 LevelDB 代码库于 2012 年创建的高性能持久化键值存储引擎。它针对 SSD 的特定特性进行了优化&#xff0c;目标是大规模&#xff08;分布式&#xff09;应用&#xff0c;并被设计为嵌入在更高层次应用中的库组件。RocksDB应用范围很…

【Python百日进阶-Web开发-音频】Day711 - 光谱表示 librosa.stft 短时傅里叶变换

文章目录 一、光谱表示 Spectral representations1.1 librosa.stft1.1.1 语法与参数1.1.2 示例 一、光谱表示 Spectral representations 1.1 librosa.stft https://librosa.org/doc/latest/generated/librosa.stft.html 1.1.1 语法与参数 librosa.stft(y, *, n_fft2048, ho…

智能机巢+无人机:自动化巡检技术详解

智能机巢与无人机的结合&#xff0c;在自动化巡检领域展现出了巨大的潜力和优势。以下是对这一技术的详细解析&#xff1a; 一、智能机巢概述 智能机巢&#xff0c;也被称为无人机机场或无人机机巢&#xff0c;是专门为无人机提供停靠、充电、维护等服务的智能化设施。它不仅…

加密与安全_优雅存储二要素(AES-256-GCM )

文章目录 什么是二要素如何保护二要素&#xff08;姓名和身份证&#xff09;加密算法分类场景选择算法选择AES - ECB 模式 (不推荐)AES - CBC 模式 (推荐)GCM&#xff08;Galois/Counter Mode&#xff09;AES-256-GCM简介AES-256-GCM工作原理安全优势 应用场景其他模式 和 敏感…

LeetcodeTop100 刷题总结(一)

LeetCode 热题 100&#xff1a;https://leetcode.cn/studyplan/top-100-liked/ 文章目录 一、哈希1. 两数之和49. 字母异位词分组128. 最长连续序列 二、双指针283. 移动零11. 盛水最多的容器15. 三数之和42. 接雨水&#xff08;待完成&#xff09; 三、滑动窗口3. 无重复字符的…

TCADE--基于迁移成分分析和差分进化的多目标多任务优化

TCADE–基于迁移成分分析和差分进化的多目标多任务优化 title&#xff1a; Multitasking multiobjective optimization based on transfer component analysis author&#xff1a; Ziyu Hua, Yulin Li, Hao Sun, Xuemin Ma. journal&#xff1a; Information Sciences (Ins)…

最优化理论与自动驾驶(十):纯跟踪算法原理、公式及代码演示

纯跟踪算法&#xff08;Pure Pursuit Algorithm&#xff09;是一种用于路径跟踪的几何控制算法&#xff0c;广泛应用于自动驾驶、机器人导航等领域。其基本思想是通过选择预定路径上的目标点&#xff08;预瞄点&#xff09;&#xff0c;并控制转向角&#xff0c;使车辆不断逼近…

用于稀疏自适应深度细化的掩码空间传播网络 CVPR2024

目录 Masked Spatial Propagation Network for Sparsity-Adaptive Depth Refinement &#xff08;CVPR 2024&#xff09;用于稀疏自适应深度细化的掩码空间传播网络1 介绍2 算法流程2.1 问题建模2.2 Guidance Network2.3 MSPN 模块 3 实验结果3.1 稀疏度自适应深度细化对比试验…

COMDEL电源CX2500S RF13.56MHZ RF GENERATOR手侧

COMDEL电源CX2500S RF13.56MHZ RF GENERATOR手侧

如何让虚拟机的服务被主机访问

当我们在虚拟机上写了一个服务器&#xff0c;在宿主机访问时&#xff0c;出现无法访问的情况。这可能是虚拟机网络的设置问题。 查看虚拟机防火墙是否关闭 在终端输入&#xff1a; systemctl status firewalld 如果是active就说明防火墙是开启的&#xff0c;需要关闭。 输入…

高级I/O知识分享【epoll || Reactor ET,LT模式】

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;Linux_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 一&#xff0c;接口 epo…

SpringBoot 消息队列RabbitMQ 消息可靠性 数据持久化 与 LazyQueue

介绍 在默认情况下&#xff0c;RabbitMQ会将接收到的信息保存在内存中以降低消息收发的延迟 一旦MO宕机&#xff0c;内存中的消息会丢失内存空间有限&#xff0c;当消费者故障或处理过慢时&#xff0c;会导致消息积压&#xff0c;引发MQ阻塞 在消息队列运行的过程中&#xf…

LeetCode 815.公交路线(BFS广搜 + 建图)(中秋快乐啊)

给你一个数组 routes &#xff0c;表示一系列公交线路&#xff0c;其中每个 routes[i] 表示一条公交线路&#xff0c;第 i 辆公交车将会在上面循环行驶。 例如&#xff0c;路线 routes[0] [1, 5, 7] 表示第 0 辆公交车会一直按序列 1 -> 5 -> 7 -> 1 -> 5 -> …