【C++类和对象(中)】—— 我与C++的不解之缘(四)

news2024/9/24 9:28:09

前言:

接下来进行类和对象中的学习,了解类和对象的默认成员函数

一、类和对象默认成员函数

        默认成员函数就是用户没有显示实现,编译器会自动生成的成员函数。

一个类,我们不显示实现的情况下,编译器就会默认生成一下留个默认成员函数。

        这里前4个(构造函数析构函数拷贝构造赋值重载)是重难点。

C++11以后还会增加两个默认成员函数,移动构造移动赋值

默认成员函数十分重要,从以下两个方面去深入了解:

  1. 我们不写时,编译器默认生成的函数行为是什么,是否满足我们的需求
  2. 编译器默认生成的函数不满足我们的需求,我们需要直接实现,那么如何自己实现呢?

        1.1、构造函数

        构造函数,是特殊的成员函数;这里需要注意,虽然名字叫做构造函数,但是构造函数的主要任务不是开辟空间创建对象(我们经常使用的局部对象是栈帧创建时,空间就已经开辟 好了),而是对象实例化时初始化对象

        这里构造函数本质上是替代实现的Stack和Data类中所写的 Init 函数,构造函数自动调用这一特点就完美替代了 Init 函数

1.1.1、构造函数的特点

构造函数的特点如下:

1、函数名和类名相同。

2、无返回值(返回值不需要写,void也不需要)。

3、对象实例化时系统会自动调用对应的构造函数。

4、构造函数可以重载

5、如果类没有显示定义构造函数,C++编译器会自动生成一个无参的默认构造函数;如果显示写了构造函数,编译器就不会再生成。

6、无参构造函数、全缺省构造函数、我们不写时编译器默认生成的构造函数,这三个都叫做默认构造函数。

7、我们不写,编译器默认生成的构造函数,对内置类型成员变量的初始化没有要求(是否初始看编译器);对于自定义类型成员变量,要求调用这个成员函数的默认构造函数初始化(如果这个成员变量没有默认构造函数,就会报错(这里要初始化这个成员变量,需要使用初始化列表来解决,后面会学习到))。

1.1.2、构造函数

        这里来看一下构造函数的前几个特点。

首先就是,构造函数的函数名和类名相同而且无返回值(不需要写返回值)

class Data
{
public:
	Data()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}

private:
	int _year;
	int _month;
	int _day;

};

        这里Data类里面的Data函数就是显示实现的构造函数(显示实现了构造函数,编译器就不会默认生成);

再来看,构造函数可以重载,我们就可以这样写:

class Data
{
public:
	Data()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	Data(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}

private:
	int _year;
	int _month;
	int _day;

};

        这里两个构造函数就形成了重载,再创建对象时,不给参数就会调用第一个构造函数,给参数就会调用第二个参数。

最后,来看对象实例化时会自动构造函数:

#include<iostream>
using namespace std;
class Data
{
public:
	Data()
	{
		cout << "Data()" << endl;
		_year = 1;
		_month = 1;
		_day = 1;
	}
	Data(int year, int month, int day)
	{
		cout << "Data(int year, int month, int day)" << endl;
		_year = year;
		_month = month;
		_day = day;
	}

private:
	int _year;
	int _month;
	int _day;

};
int main()
{
	Data d1;
	Data d2(2006, 7, 20);

	return 0;
}

1.1.3、默认构造函数

默认构造函数有三种:

        无参构造函数全缺省构造函数和我们不写时编译器默认生成的构造函数

这三个函数有且只有一个存在(不能同时存在);

        这里虽然无参构造函数和全缺省构造函数形成函数重载,但是在函数调用时会存在歧义:

#include<iostream>
using namespace std;
class Data
{
public:
	Data()
	{
		cout << "Data()" << endl;
		_year = 1;
		_month = 1;
		_day = 1;
	}
	Data(int year = 1, int month = 1, int day = 1)
	{
		cout << "Data(int year, int month, int day)" << endl;
		_year = year;
		_month = month;
		_day = day;
	}

private:
	int _year;
	int _month;
	int _day;

};
int main()
{
	Data d1;

	return 0;
}

这里总结一下,编译传实参就可以调用的构造就是默认构造。

1.1.4、编译器默认生成的默认构造函数        

        编译器默认生成的构造函数,对于内置类型(整型,浮点型,字符类型,指针等)初始化没有要求,可能会初始化,也可能不做任何处理;对于自定义类型成员变量初始化会调用这个成员变量的默认构造函数(如果不存在默认构造就报错)。

        所以,大多情况下我们都需要自己实现构造函数。

        1.2、析构函数

        析构函数与构造函数的功能相反,析构函数不是完成对象本身的销毁(局部对象是存在栈帧的,函数结束栈帧就销毁了,局部对象就自动释放了);C++规定在销毁时会自动调用析构函数,完成对像中资源的清理释放工作。

        相关函数的功能类比之前 Stack 栈实现的DesTroy 销毁功能,对申请资源进行释放。

1.2.1、析构函数特点

1、析构函数名是在类名前面加上字符 ~

2、无参数返回值(与构造函数一样,不需要加void)。

3、一个类只能有一个析构函数,如果没有显示定义,系统就会自动生成默认的析构函数。

4、对象生命周期结束时,系统就会自动调用析构函数。

5、与构造函数类似,我们不显示写,编译器默认生成的对内置类型不做处理,自定义类型就会调用它的析构函数。

6、这里需要注意,我们显示写了析构函数,对于自定义类型也会调用它的析构函数(也就是说,无论说明情况下,自定义类型都会自动调用析构函数。

7、如果类没有申请资源,析构函数可以不写,直接使用编译器生成的默认析构函数,就比如Data(日期类);如果默认生成的析构就满足我们的需求,不用写,比如MyQueue(用两个栈实现的队列);如果有资源申请,一定要自己写析构,否则就会造成资源泄漏,比如Stack(栈)。

8、一个局部域的多个对象,C++ 规定后定义的先调用析构

1.2.2、析构函数

自己实现析构函数,这里拿栈Stack类来举例:

class Stack
{
public:
	//构造函数
	Stack(int capacity = 4)
	{
		cout << "Stack" << endl;
		_arr = (int*)malloc(sizeof(int) * capacity);
		if (_arr == NULL)
		{
			perror("malloc fail");
			return;
		}
		_capacity = capacity;
		_top = 0;
	}

	//析构函数
	~Stack()
	{
		cout << "~Stack" << endl;
		if (_arr)
			free(_arr);
		_arr = nullptr;
		_capacity = _top = 0;
	}
private:
	int* _arr;
	int _top;
	int _capacity;
};

        这里,对象生命周期结束时会自动调用析构函数,看一下释放真的调用了?

int main()
{
	Stack st;

	return 0;
}

1.2.3、自定义类型自动调用其析构函数

        对于自定义类型,无论我们写函数不写析构,都会自动调用其析构函数。

class Stack
{
public:
	//构造函数
	Stack(int capacity = 4)
	{
		cout << "Stack" << endl;
		_arr = (int*)malloc(sizeof(int) * capacity);
		if (_arr == NULL)
		{
			perror("malloc fail");
			return;
		}
		_capacity = capacity;
		_top = 0;
	}

	//析构函数
	~Stack()
	{
		cout << "~Stack" << endl;
		if (_arr)
			free(_arr);
		_arr = nullptr;
		_capacity = _top = 0;
	}
private:
	int* _arr;
	int _top;
	int _capacity;
};
class MyQueue
{
public:

private:
	Stack pushst;
	Stack popst;
};
int main()
{

	MyQueue mq;

	return 0;
}

        

        这里可以看到,自定义类型构造和析构都调用了它的构造函数和析构函数。

        1.3、拷贝构造函数

        如果构造函数的第一个参数是自身类类型的引用,且任何额外的参数都有默认值,则此构造函数也叫做拷贝构造函数(也就是拷贝构造函数是特殊的构造函数)。

1.3.1、拷贝构造的特点

1、拷贝构造函数是构造函数的一个重载。

2、C++规定,自定义类的对象进行拷贝行为必须调用拷贝构造,所以这里自定义类型传值传参和传值返回都会调用拷贝构造完成。

3、拷贝构造的第一个参数必须是类类型对象的引用,使用传值方式编译器直接报错,因为语法逻辑上会引发无穷递归。

4、如果未显示定义拷贝构造,编译器会自动生成拷贝构造函数;

5、  像Date这样的类成员变量全是内置类型且没有指向什么资源,编译器⾃动⽣成的拷⻉构造就可以完 成需要的拷⻉,所以不需要我们显⽰实现拷⻉构造。

        像Stack这样的类,虽然也都是内置类型,但 是_a指向了资源,编译器⾃动⽣成的拷⻉构造完成的值拷⻉/浅拷⻉不符合我们的需求,所以需要我们⾃⼰实现深拷⻉(对指向的资源也进⾏拷⻉)。

        像MyQueue这样的类型内部主要是⾃定义类型 Stack成员,编译器⾃动⽣成的拷⻉构造会调⽤Stack的拷⻉构造,也不需要我们显⽰实现

MyQueue的拷⻉构造。
6、    传值返回会产⽣⼀个临时对象调⽤拷⻉构造,传值引⽤返回,返回的是返回对象的别名(引⽤),没有产⽣拷⻉。但是如果返回对象是⼀个当前函数局部域的局部对象,函数结束就销毁了,那么使⽤ 引⽤返回是有问题的,这时的引⽤相当于⼀个野引⽤,类似⼀个野指针⼀样。传引⽤返回可以减少 拷⻉,但是⼀定要确保返回对象,在当前函数结束后还在,才能⽤引⽤返回。

1.3.2、拷贝构造参数

        C++规定自定义类型对象拷贝时必须调用拷贝构造:

class Data
{
public:
	//构造
	Data(int year = 1 , int month = 1, int day = 1)
	{ 
		cout << "Data(int year, int month, int day)" << endl;
		_year = year;
		_month = month;
		_day = day;
	}
	//拷贝构造
	Data(Data& d)
	{
		cout << "Data(Data&)" << endl;
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
private:
	int _year;
	int _month;
	int _day;

};
int main()
{
	Data d1(2006, 7, 20);
	Data d2(d1);
	Data d3 = d1;
	return 0;
}

        拷贝构造函数的第一个参数必须是类类型对象的引用,如果使用传值调用:

就会像下面这样,名称传参都会调用拷贝构造,调用完传参再次调用拷贝构造,无穷递归下去。

1.3.3、编译器默认生成的拷贝构造函数

        编译器默认生成的拷贝构造,对内置类型成员会完成值拷贝/浅拷贝(一个字节一个字节的拷贝),对自定义类型成员变量就会调用它的拷贝构造函数。

二、赋值运算符重载

        2.1、运算符重载

1、当运算符被用于类类型的对象时,C++语言允许我们通过运算符重载的形式指定新的含义。C++规定类类型对象使用运算符时,必须转换成调用对应运算符重载,若没有对应的运算符重载,则会编译报错。

2、运算符重载是具有特殊名字的函数,他的名字是由operator后面要定义的运算符共同构成。和其他函数一样,它也具有其返回类型和参数列表以及函数体。

3、重载运算符函数的参数个数和该运算符作用的运算对象数量一样多。一元运算符有一个参数,二元运算符有两个参数,二元运算符的左侧运算对象传给第一个参数,右侧运算对象传给第二个参数。

4、如果一个重载运算符函数是成员函数,则它的第一个运算对象默认传给隐式的this指针,因此运算符重载作为成员函数时,参数比运算对象少一个。

5、运算符重载以后,其优先级和结合性与对应的内置类型运算符保持一致。

6、不能通过连接语法中没有的符号来创建新的操作符:比如operator@

7、.*    ::   sizeof   ?:   .   注意以上5个运算符不能重载。(选择题里面常考,要记一
重载操作符至少有一个类类型参数,不能通过运算符重载改变内置类型对象的含义,如: int
operator+(int x,int y)

8、一个类需要重载哪些运算符,是看哪些运算符重载后有意义,比如Date类重载operator-就有意义,但是重载operator+就没有意义。

9、  重载++运算符时,有前置++和后置++,运算符重载函数名都是operator++,无法很好的区分。
        C++规定,后置++重载时,增加一个int形参,跟前置++构成函数重载,方便区分。

10、重载<<>>时,需要重载为全局函数,因为重载为成员函数,this指针默认抢占了第一个形参位置,第一个形参位置是左侧运算对象,调用时就变成了对象<<cout,不符合使用习惯和可读性。重载为全局函数把ostream/istream放到第一个形参位置就可以了,第二个形参位置当类类型对象。

有了运算符重载,对于自定义类型的对象,我们就可以像内置类型那样,直接进行+/-/+=/-= 等操作。(要 根据自定义类的需求写)。

应用举例:

        这里以日期类为例,实现一个运算符重载 ==

//运算符重载
// == 
bool Data::operator==(Data& d)
{
	if (_year == d._year && _month == d._month && _day == d._day)
	{
		return true;
	}
	return false;
}

常见的运算符重载

        我们基本上可以重载所以的算术运算符、关系运算符和赋值运算符等,

算术运算符:+、-、*、/ ,用于自定义类型的算术运算。
关系运算符:==、!=、<、>、<=、>= ,用于自定义类型的比较操作。
赋值运算符:=,用于自定义类型的赋值操作。(当自定义类型(栈)包含动态分配的内存时,需要深拷贝以避免悬挂指针等问题。)
自增自减运算符:++、--,用于自定义类型的自增和自减操作。
下标运算符:[ ],用于自定义类型的数组或类似数组的操作。
流插入和提取运算符:<<、>>,用于自定义类型的输入输出操作。
函数调用运算符:(),允许自定义类型的对象像函数一样被调用。
成员访问运算符:->,一般 与智能指针或类似智能指针的类一起使用,用于访问指针所指向对象的成员。

前置++和后置++重载

C++规定

后置++重载时,增加一个int形参,跟前置++构成函数重载,方便区分。

前置++ 先使用再+1;而后置++是先+1再使用。

//前置++
Data& operator++();
//后置++
Data& operator++(int);

        2.2、赋值运算符重载

        赋值运算符重载是一个默认成员函数,用于完成两个已经存在的对象直接的拷贝赋值,这里要注意跟拷贝构造区分,拷贝构造用于一个对象拷贝初始化给另一个要创建的对象。

1、赋值运算符重载是一个运算符重载,规定必须重载为成员函数。赋值运算重载的参数建议写成1.const 当前类类型引用,否则会传值传参会有拷贝

2、有返回值,且建议写成当前类类型引用,引用返回可以提高效率,有返回值目的是为了支持连续赋值场景。

3、没有显式实现时,编译器会自动生成一个默认赋值运算符重载,默认赋值运算符重载行为跟默认拷3贝构造函数类似,对内置类型成员变量会完成值拷贝/浅拷贝(一个字节一个字节的拷贝),对自定义类型成员变量会调用他的赋值重载函数。

4、  像Date这样的类成员变量全是内置类型且没有指向什么资源,编译器自动生成的赋值运算符重载就4可以完成需要的拷贝,所以不需要我们显示实现赋值运算符重载。

        像Stack这样的类,虽然也都是内置类型,但是 a指向了资源,编译器自动生成的赋值运算符重载完成的值拷贝/浅拷贝不符合我们的需求,所以需要我们自己实现深拷贝(对指向的资源也进行拷贝)。

        像MyQueue这样的类型内部主要是自定义类型Stack成员,编译器自动生成的赋值运算符重载会调用Stack的赋值运算符重载也不需要我们显示实现MyQueue的赋值运算符重载。

这里还有一个小技巧,如果一个类显示实现了析构并释放资源,那么他就需要显示写赋值运算符重载,否则就不需要。

        现在就来哦实现日期类巩固这方面的知识。

        2.3、日期类的实现

Data.h:

#pragma once
#include<iostream>
#include<assert.h>
class Data
{
	friend std::ostream& operator<<(std::ostream& out, const Data& d);
	friend std::istream& operator>>(std::istream& in, Data& d);
public:
	//构造函数
	Data(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	//析构
	
	//拷贝构造
	Data(Data& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	//输出
	void Print();

	//运算符重载
	bool operator==(Data& d);
	bool operator!=(Data& d);
	bool operator<(Data& d);
	bool operator<=(Data& d);
	bool operator>(Data& d);
	bool operator>=(Data& d);

	Data& operator+=(int day);
	Data& operator+(int day);
	Data& operator-=(int day);
	Data& operator-(int day);
	int operator-(Data& d);

	Data& operator++();
	Data& operator++(int);
	Data& operator--();
	Data& operator--(int);

	//ostream& operator<<(ostream& out);
private:
	int _year;
	int _month;
	int _day;
};

Data.cpp:

#include"Data.h"
using namespace std;

//获得当前月份天数
int GetMonthDay(int year, int month)
{
	assert(month > 0 && month < 13);
	static int arr[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 40 == 0)))
	{
		return 29;
	}
	return arr[month];
}
//输出
void Data::Print()
{
	cout << _year << "年" << _month << "月" << _day << "日" << endl;
}
//运算符重载
// == 
bool Data::operator==(Data& d)
{
	if (_year == d._year && _month == d._month && _day == d._day)
	{
		return true;
	}
	return false;
}
// !=
bool Data::operator!=(Data& d)
{
	return !(*this == d);
}

// < 
bool Data::operator<(Data& d)
{
	if (_year < d._year)
	{
		return true;
	}
	else if (_year == d._year && _month < d._month)
	{
		return true;
	}
	else if (_year == d._year && _month == d._month && _day < d._day)
	{
		return true;
	}

	return false;
}
//  <=
bool Data::operator<=(Data& d)
{
	return (*this) == d || (*this) < d;
}
// >
bool Data::operator>(Data& d)
{
	if (_year > d._year)
	{
		return true;
	}
	else if (_year == d._year && _month > d._month)
	{
		return true;
	}
	else if (_year == d._year && _month == d._month && _day > d._day)
	{
		return true;
	}

	return false;
}
// +=
bool Data::operator>=(Data& d)
{
	return (*this) == d || (*this) > d;
}
Data& Data::operator+=(int day)
{
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		_month++;
		if (_month == 13)
		{
			_month = 1;
			_year++;
		}
	}
	return *this;

}
// +
Data& Data::operator+(int day)
{
	Data tmp = *this;
	tmp += day;
	return tmp;
}

// -=
Data& Data::operator-=(int day)
{
	_day -=day;
	while (_day <= 0)
	{
		_month--;
		if (_month == 0)
		{
			_month = 12;
			_year--;
		}
		_day += GetMonthDay(_year, _month);
	}
	return (*this);
}
// - 天数
Data& Data::operator-(int day)
{
	Data d(*this);
	d -= day;
	return d;
}

// - 日期
int Data::operator-(Data& d)
{
	Data min(*this);
	Data max(d);
	if ((*this) > d)
	{
		min = d;
		max = *this;
	}int count = 0;
	while (min != max)
	{
		count++;
		min += 1;
	}
	return count;
	
}
//++
//前置++
Data& Data::operator++()
{
	(*this) += 1;
	return *this;
}
//后置++
Data& Data::operator++(int)
{
	Data d(*this);
	(*this) += 1;
	return d;
}

//前置--
Data& Data::operator--()
{
	(*this) -= 1;
	return *this;
}
//后置--
Data& Data::operator--(int)
{
	Data d(*this);
	(*this) -= 1;
	return d;
}

// <<
//ostream& Data::operator<<(ostream& out)
//{
//	out << _year << "年 " << _month << "月 " << _day << "日 " << endl;
//	return out;
//}
std::ostream& operator<<(std::ostream& out, const Data& d)
{
	cout << d._year << "年" << d._month << "月" << d._day << "日" << endl;

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

三、取地址运算符重载

        3.1、const 成员函数

1、 将const修饰的成员称之为从const成员函数,const成员放到成员函数参数列表的后面。

2、 const实际修饰该成员函数的this指针,表明在该成员函数中不能对类的任何成员进行修改。

3、 const修饰Data类的Print成员函数,

Print隐含的this指针由Data* const this 变为const Data* const this

#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	// void Print(const Date* const this) const
	void Print() const
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	// 这⾥⾮const对象也可以调⽤const成员函数是⼀种权限的缩⼩
	Date d1(2024, 7, 5);
	d1.Print();
	const Date d2(2024, 8, 5);
	d2.Print();
	return 0;
}

        3.2、 取地址运算符重载

        取地址运算符重载分为普通取地址运算符重载和const取地址运算符重载,一般这两个函数编译器自动生成的就可以够我们用了,不需要去显示实现。

class Data
{
public:
	Data* operator&()
	{
		return this;
	}
	const Data* operator&()const
	{
		return this;
	}
private:
	int _year;
	int _month;
	int _day;
};

这里我们不想要访问到类对象的地址,也可以返回nullptr。

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

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

相关文章

无人机开启农林植保新篇章

嘿&#xff0c;小伙伴们&#xff0c;你们知道吗&#xff1f;无人机已经悄悄在农业领域大展拳脚&#xff0c;成为现代农业的“黑科技”新宠儿啦&#xff01; 想象一下&#xff0c;广袤的田野上空&#xff0c;无人机如同勤劳的蜜蜂&#xff0c;精准高效地完成着各项任务&#xff…

unity 使用 compute shader的步骤

这里详细的记载使用步骤&#xff0c;我这个例子是让一个立方体上下不停的动 创建一个compute shader 一个普通shader 一个材质 一个C# 先挨个写上类容 这里kernel 指定main函数入口&#xff0c;RWStructuredBuffer就是数组&#xff0c;具体size是在外部指定的&#xff0c;可能…

C#使用CEFSharp获取动态网页源码

CEF 全称是Chromium Embedded Framework&#xff08;Chromium嵌入式框架&#xff09;&#xff0c;是个基于Google Chromium项目的开源Web browser控件&#xff0c;支持Windows, Linux, Mac平台。CEFSharp就是CEF的C#移植版本。 访问以下链接可以获取CEF的详细介绍 chromiumem…

c++版opencv长文指南

c版opencv长文指南 1、配置opencv库1.1 下载1.2 配置1.2.1 配置包含目录1.2.2 配置库含目录1.2.3 配置链接器1.2.4 配置系统环境变量 2、学习路线3、入门知识3.1 图像读取与显示3.2 图像色彩空间转换3.2 图像对象的创建与赋值3.2.1 图像对象的创建3.2.2 图像对象的赋值 3.3 图像…

轻松搞定小程序生成短链接/二维码,你学会了吗?

朋友们&#xff0c;大家有没有遇到过这样的困扰&#xff1a;小程序由于不是链接&#xff0c;在短信或者其他平台里根本没法推广&#xff0c;导致小程序的用户量很难涨起来。 那小程序转成链接真的就没办法实现吗&#xff1f;当然不是&#xff01; 现在有一款超实用的工具——…

zigbee笔记:十、ZStack(2.3.0-1.4.0)的OSAL使用分析

zigbee笔记&#xff1a;九中&#xff0c;我们已经学会了利用模板&#xff0c;定制自己的个性开发工程&#xff0c;本文为协议栈&#xff08;ZStack-CC2530-2.3.0-1.4.0&#xff09;代码使用分析笔记&#xff0c;来进一步掌握协议栈的使用。 一、协议栈使用知识点 1、协调器、路…

python从入门到精通:基础语法讲解

1、字面量 字面量&#xff1a;在代码中&#xff0c;被写下来的固定的值&#xff0c;称之为字面量。 python中常用的几种数据类型&#xff1a; 类型描述说明数字&#xff08;Number&#xff09; 整数&#xff08;int&#xff09; 浮点数&#xff08;float&#xff09; 复数&a…

Graph-Cot:图上迭代推理

Graph-Cot&#xff1a;图上迭代推理 提出背景GRAPH-COT 对比 MindMapGRAPH-COT 和 MindMap 多链推理方法结合案例一&#xff1a;复杂症状的诊断案例二&#xff1a;罕见病的诊断案例三&#xff1a;治疗方案的制定 解法拆解目的问题解法 GRAPH-COT 医学问诊 论文&#xff1a;http…

(BO)Bayes-CNN多变量时序预测 基于贝叶斯算法-卷积神经网络多变量时序预测(多输入单输出)Matlab代码

Bayes-CNN多变量时序预测 基于贝叶斯算法-卷积神经网络多变量时序预测&#xff08;多输入单输出&#xff09;Matlab代码 程序已经调试好&#xff0c;无需更改代码替换数据集即可运行&#xff01;&#xff01;&#xff01;数据格式为excel&#xff01;(如下) 需要其他的都可以…

CSS3下拉菜单实现

导航菜单&#xff1a; <nav class"multi_drop_menu"><!-- 一级开始 --><ul><li><a href"#">Power</a></li><li><a href"#">Money</a></li><li><a href"#"…

【数模修炼之旅】02 多目标规划 深度解析(教程+代码)

【数模修炼之旅】02 多目标规划 深度解析&#xff08;教程代码&#xff09; 接下来 C君将会用至少30个小节来为大家深度解析数模领域常用的算法&#xff0c;大家可以关注这个专栏&#xff0c;持续学习哦&#xff0c;对于大家的能力提高会有极大的帮助。 1 多目标规划介绍及应…

百度智能云发布3款轻量级+2款场景大模型

文心大模型ERNIE 3.5是目前百度智能云千帆大模型平台上最受欢迎的基础大模型之一。针对用户的常见通用的对话场景&#xff0c;ERNIE 3.5 在指令遵循、上下文学习和逻辑推理能力三方面分别进行了能力增强。 ERNIE Speed作为三款轻量级大模型中的“大个子”&#xff0c;推理场景…

解决连接不上Linux和服务器中的Nacos(Windows中能连接但是Linux中却不行)

报错 com.alibaba.nacos.shaded.io.grpc.StatusRuntimeException: UNKNOWN: Uncaught exception in the SynchronizationContext. Re-thrown. at com.alibaba.nacos.shaded.io.grpc.Status.asRuntimeException(Status.jav 2024-08-13T10:21:52.93708:00 ERROR 27764 --- …

ArduPilot开源代码之FMU+IOMCU设计

ArduPilot开源代码之FMUIOMCU设计 1. 源由2. 设计概念3. FMU & IOMCU特点3.1 FMU&#xff08;Flight Management Unit&#xff09;的主要功能3.2 IOMCU&#xff08;Input/Output Microcontroller Unit&#xff09;的主要功能3.3 主要差异 4. 主/辅助(MAIN/AUX) PWM输出5. 软…

【北京仁爱堂】痉挛性斜颈的早期症状,你了解吗?

在日常生活中&#xff0c;您可能很少听到“痉挛性斜颈”这个名词&#xff0c;但它却是一种不容忽视的疾病。今天&#xff0c;就让我们一起来了解一下痉挛性斜颈的早期症状&#xff0c;以便能够及时发现并采取相应的措施。 痉挛性斜颈是一种局限性肌张力障碍疾病&#xff0c;主要…

Gitlab搭建服务器好做吗 Gitlab搭建服务器操作指南

GitLab是一个强大的开源代码托管和CI/CD工具&#xff0c;广泛用于软件开发的版本控制和自动化构建。对于许多公司和开发团队来说&#xff0c;自行搭建GitLab服务器是一个既具挑战性又有很多好处的选择。本文将详细讨论搭建GitLab服务器的难易程度&#xff0c;提供一份详尽的操作…

死信队列.

“死信”是指在RabbitMQ中那些因为某些原因无法被正常处理的消息。

OpenCV图像滤波(11)中值滤波medianBlur函数的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 功能描述 该函数使用中值滤波器对图像进行模糊处理。 该函数采用 ksizeksize 的窗口尺寸对图像进行平滑处理。对于多通道图像&#xff0c;每个通道将被独…

Linux发行版深度对比:Ubuntu、CentOS与Fedora

在Linux的广阔世界中&#xff0c;Ubuntu、CentOS和Fedora作为三大主流发行版&#xff0c;各自拥有独特的生态系统、用户基础和开发理念。它们不仅在技术架构上有着显著的差异&#xff0c;更在用户体验、社区支持、软件更新策略以及安全性能等方面展现出各自的特色。本文将对这三…

红黑树R-B Tree

文章目录 概述红黑树的特性红黑树的原理应用为什么设计红黑树红黑树左旋与右旋的区别 概述 红黑树&#xff08;Red Black Tree&#xff09;是一种自平衡的二叉查找树&#xff0c;在计算机科学中广泛使用&#xff0c;其典型的用途是实现关联数组。R-B Tree&#xff0c;全称是 R…