【C++】构造函数、析构函数、拷贝构造与运算符重载

文章目录

  • 1.类的六个默认构造函数
  • 2.构造函数
    • 2.1特性
      • 2.1.1 函数名与类名相同
      • 2.1.2. 无返回值(不能写void)
      • 2.1.3. 对象实例化时编译器自动调用对应的构造函数
      • 2.1.4 构造函数可以重载
      • 2.1.5编译器生成默认的构造函数
      • 2.1.6编译器生成的默认构造有何用?
      • 2.1.7三种默认构造函数
  • 3.析构函数
    • 3.1特性
      • 3.1.1析构函数名是在类名前加上字符 ~
      • 3.1.2无参数无返回值类型(不能写void)
      • 3.1.3一个类只能有一个析构函数。
      • 3.1.4对象生命周期结束时,编译系统自动调用析构函数
      • 3.1.5编译器生成的默认析构函数
  • 4.拷贝构造
    • 4.1特征
      • 4.1.1拷贝构造函数是构造函数的一个重载形式
      • 4.1.2拷贝构造函数的参数
      • 4.1.3编译器生成默认的拷贝构造函数(浅拷贝)
      • 4.1.4拷贝构造函数典型调用场景:
  • 5.赋值运算符重载
    • 5.1运算符重载
    • 5.2赋值运算符重载
      • 5.2.1赋值运算符重载格式
      • 5.2.2返回值类型
      • 5.2.3检测是否自己给自己赋值
      • 5.2.4注意返回值
      • 5.2.5重载成类的成员函数
      • 5.2.6默认赋值运算符重载
    • 5.3前置++与后置++重载
    • 5.4运算符重载拓展
  • 6.const成员函数
  • 7.取地址及const取地址操作符重载

在这里插入图片描述

1.类的六个默认构造函数

如果一个类中什么成员都没有,简称为空类。

class test
{

};

空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。

默认成员函数用户没有显式实现编译器自动生成的成员函数称为默认成员函数。
在这里插入图片描述

2.构造函数

class Data
{
public:
	void Init(int year = 1, int month = 1, int day = 1)
	{
		this->_year = year;
		this->_month = month;
		this->_day = day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1;
	d1.Init(2024, 5, 22);
	d1.Print();

	Data d2;
	d2.Init(2024, 5, 21);
	d2.Print();
	return 0;
}

对于上方的Date类,可以通过 Init 公有方法给对象设置日期,但如果每次创建对象时都调用该方法设置信息,未免有点麻烦,那能否在对象创建时,就将信息设置进去呢?

构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。

2.1特性

构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象

特性:

2.1.1 函数名与类名相同

2.1.2. 无返回值(不能写void)

在这里插入图片描述

2.1.3. 对象实例化时编译器自动调用对应的构造函数

在这里插入图片描述

2.1.4 构造函数可以重载

在这里插入图片描述

特别注意:在调用无参构造时,后面不能跟括号。
在这里插入图片描述

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

如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数一旦用户显式定义编译器将不再生成

未显示定义,编译器自动生成,可以通过编译

在这里插入图片描述

若显示定义了构造函数,编译器不再生成;即没有默认构造函数,编译报错。

在这里插入图片描述

2.1.6编译器生成的默认构造有何用?

不实现构造函数的情况下,编译器会生成默认的构造函数。但是看起来默认构造函数又没什么用?
下面代码中,d对象调用了编译器生成的默认构造函数,但是d对象_year/_month/_day,依旧是随机值。也就说在这里编译器生成的默认构造函数并没有什么用??
在这里插入图片描述

存在即合理,它还是有一定的用处的。
C++把类型分成内置类型(基本类型)和自定义类型。

  • 内置类型就是语言提供的数据类型,如:int/char/float/任何类型的指针…,
  • 自定义类型就是我们使用class/struct/union等自己定义的类型,

对于内置类型来说,C++标准并没有规定要不要处理(可处理,可不处理,取决于编译器)

对于自定义类型来说,会调用该类型的默认构造函数

看看下面的程序,就会发现编译器生成默认的构造函数会对自定类型成员 _t 调用的它的默认成员函数。
在这里插入图片描述

注意::C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在类中声明时可以给默认值(类中不是定义,类的实例化才是定义,易错
在这里插入图片描述

2.1.7三种默认构造函数

无参的构造函数全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。

三种默认构造函数:

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

注意:无参构造与全缺省的构造只能存在一个,否则会存在调用歧义
在这里插入图片描述

总结:

  • 无需传参就可以调用的构造函数就是默认构造函数
  • 一般情况下,构造函数都需要我们显示的去实现。
  • 只有少数情况下可让编译器自动生成构造函数,例如成员全是自定义类型

3.析构函数

析构函数:与构造函数功能相反,析构函数不是完成对象本身的销毁工作,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。

3.1特性

3.1.1析构函数名是在类名前加上字符 ~

3.1.2无参数无返回值类型(不能写void)

在这里插入图片描述

3.1.3一个类只能有一个析构函数。

一个类只能有一个析构函数若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载。

3.1.4对象生命周期结束时,编译系统自动调用析构函数

可以借助调试看一眼,我们并没有调用析构函数,但是在代码179行按F11会自动进入析构函数。

在这里插入图片描述

上面的代码我们好像没有看出来析构函数有什么用,那就看下面的代码:
下方代码我们简单的实现了一个栈,此时编译器自动调用栈所实现的析构函数,会将我们所申请的资源清理掉。

typedef int DataType;
class Stack
{
public:
	//构造
	Stack(size_t capacity = 3)
	{
		this->_array = (DataType*)malloc(sizeof(DataType) * capacity);
		if (NULL == _array)
		{
			perror("malloc申请空间失败!!!");
			return;
		}
		this->_capacity = capacity;
		this->_size = 0;
	}
	void Push(DataType data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	//析构
	~Stack()
	{
 		if (_array)
		{
			free(_array);
			_array = NULL;
			_capacity = 0;
			_size = 0;
		}
	}
private:
	DataType* _array;
	int _capacity;
	int _size;
};
int main()
{
	Stack s;
	s.Push(1);
	s.Push(2);
	return 0;
}

在这里插入图片描述

3.1.5编译器生成的默认析构函数

关于编译器自动生成的析构函数,是否会完成一些事情呢?
下面的程序我们会看到,编译器生成的默认析构函数,对自定类型成员调用它的析构函数;对内置类型成员不做处理。

在这里插入图片描述

总结:

  1. 有资源需要清理的,就需要写析构函数,否则会造成内存泄漏问题。如:栈、链表…
  2. 有两种情况不需要写析构,编译器默认生成的就可以
    a.全是内置类型的成员,没有资源需要清理的。如Date类…
    b.内置类型成员无需清理,其它都是自定义类型的成员。如两个栈实现一个队列

4.拷贝构造

在创建对象时,可否创建一个与已存在对象一模一样的新对象呢?

拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象由编译器自动调用

4.1特征

拷贝构造函数也是特殊的成员函数,其特征如下:

4.1.1拷贝构造函数是构造函数的一个重载形式

没有返回值

class Date
{
public:
	//构造函数
	Date(int year, int month, int day)
	{
		this->_year = year;
		this->_month = month;
		this->_day = day;
	}
	//拷贝构造
	Date(const Date& d)
	{
		this->_year = d._year;
		this->_month = d._month;
		this->_day = d._day;
	}

private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2024,5,24);

	//拷贝构造
	//以下两种方式等价
	Date d2(d1);
	Date d3 = d1;
	return 0;
}

4.1.2拷贝构造函数的参数

拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。
在这里插入图片描述
为什么会引起无穷递归呢?

首先我们要知道,自定义类型传值传参要调用拷贝构造(可以看成一种规定)

下面的代码调试可以发现,当我们第一次按F11进入fun函数时,它是先进入到了Date类中的拷贝构造函数,第二次按F11才会进入fun函数。
在这里插入图片描述

如果这样,不写引用的话就会引发无穷的递归。

本来是只想调用拷贝构造,但是调用前要传参数,传递参数又要发生拷贝构造;那么还是要传递参数,此时就会形成没有尽头的递归,
在这里插入图片描述

4.1.3编译器生成默认的拷贝构造函数(浅拷贝)

若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。

我们发现,对于所有成员确实都拷贝过去了,可是对于数组元素来说,它们两个数组的地址是相同的,也就是二者数组的同一块空间,这就有点不好了。
在这里插入图片描述
注意:
在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的;而自定义类型是调用其拷贝构造函数完成拷贝的。

4.1.4拷贝构造函数典型调用场景:

  • 使用已存在对象创建新对象
  • 函数参数类型为类类型对象
  • 函数返回值类型为类类型对象
class Date
 {
 public:
    Date(int year, int minute, int day)
    {
        cout << "Date(int,int,int):" << this << endl;
    }
    Date(const Date& d)
    {
        cout << "Date(const Date& d):" << this << endl;
    }
    ~Date()
    {
        cout << "~Date():" << this << endl;
    }
 private:
    int _year;
    int _month;
    int _day;
 };
 Date Test(Date d)
 {
    Date temp(d);
    return temp;
 }
 int main()
 {
    Date d1(2022,1,13);
    Test(d1);
    return 0;
 }

在这里插入图片描述

总结:

  • 如果没有管理资源,一般不需要写拷贝构造,默认生成的拷贝构造就可以。如Data
  • 如果都是自定义类型的成员,内置类型成员也没有指向资源,也类似默认生成的拷贝构造就可以。如两个栈实现队列
  • 一般情况下,不需要显示的写析构函数,就不需要显示的写拷贝构造
  • 如果内部有指针或一些值指向资源,需要写析构释放,通常就需要显示写构造完成深拷贝。如:Stack、List等。

5.赋值运算符重载

我们写了这么多的日期类,好像都没怎么操作过,下面写个日期的比较吧:
比如我们写个函数比较两个日期哪个小,那么我们就得这样写:

bool CompareLess(Date& d1, Date& d2)
{
	if (d1._year < d2._year)
	{
		return true;
	}
	else if(d1._year == d2._year)
	{
		if (d1._month < d2._month)
		{
			return true;
		}
		else if (d1._month == d2._month)
		{
			return d1._day < d2._day;
		}
	}
	return false;
}

如果比较两个日期哪个大呢?是不是又得写一份类似的代码,而且调用的时候可读性又不好,如下:

bool CompareLarger(Date& d1, Date& d2)
{
	if (d1._year > d2._year)
	{
		return true;
	}
	else if (d1._year == d2._year)
	{
		if (d1._month > d2._month)
		{
			return true;
		}
		else if (d1._month == d2._month)
		{
			return d1._day > d2._day;
		}
	}
	return false;
}
int main()
{
	Date d1(2024, 6, 25);
	Date d2(2024, 6, 1);
	Date d3(2025, 6, 1);
	cout << CompareLess(d1, d2) << endl;
	cout << CompareLess(d2, d3) << endl;
	return 0;
}

那能不能像内置类型那样直接用> < 这样比呢?那样多得劲。但是很遗憾,C++不支持这样写

在这里插入图片描述

但是祖师爷发明了运算符重载来支持这样写。

5.1运算符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型和参数列表与普通的函数类似。

函数名字为:关键字operator 后面接需要重载的运算符符号
函数原型:返回值类型 operator操作符(参数列表)

//全局的两个函数
//bool CompareLess(Date& d1, Date& d2)
bool operator<(Date& d1, Date& d2)//操作符重载
{
	if (d1._year < d2._year)
	{
		return true;
	}
	else if(d1._year == d2._year)
	{
		if (d1._month < d2._month)
		{
			return true;
		}
		else if (d1._month == d2._month)
		{
			return d1._day < d2._day;
		}
	}
	return false;
}

//bool CompareLarger(Date& d1, Date& d2)
bool operator>(Date& d1, Date& d2)//操作符重载
{
	if (d1._year > d2._year)
	{
		return true;
	}
	else if (d1._year == d2._year)
	{
		if (d1._month > d2._month)
		{
			return true;
		}
		else if (d1._month == d2._month)
		{
			return d1._day > d2._day;
		}
	}
	return false;
}

int main()
{
	Date d1(2024, 6, 25);
	Date d2(2024, 6, 1);
	Date d3(2025, 6, 1);
	//显示调用
	cout << operator>(d1, d2) << endl;

	//隐式调用
	cout << (d1 < d2) << endl;

	cout << (d2 > d3) << endl;
	return 0;
}

注意:

  • 不能通过连接其他符号来创建新的操作符:比如operator@

在这里插入图片描述

  • 重载操作符 必须有一个类类型参数(即不可以重新定义内置类型已经存在的操作符的行为)

在这里插入图片描述

  • .* (点星)、 :: (域限定符) 、sizeof 、?:(三目运算符) . (成员点)。注意以上5个运算符不能重载。这个经常在笔试选择题中出现。
  • 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
    我们一般将运算符重载放在类中,而不是类外。因为成员变量通常是私有的,在类外是访问不到的,所以通常将函数重载作为类的成员函数。(上面代码可以访问是因为将它放为public了)

在这里插入图片描述

5.2赋值运算符重载

5.2.1赋值运算符重载格式

参数类型:const T&,传递引用可以提高传参效率

5.2.2返回值类型

返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值

假设有下面的代码,我想让d1变成d4,那会发生什么呢?
在这里插入图片描述
此时调用的不是拷贝构造,而是一个赋值拷贝(将一个已经存在的对象,拷贝赋值给另一个已经存在的对象)

那赋值应该怎么写呢?下面这样写就可以吗?
在这里插入图片描述

但是很多人都不是这样写的,别人是这样写的,有一个返回值:

在这里插入图片描述

这样写是因为可能存在连续的赋值

int main()
{
	Date d1(2024, 5, 27);

	//拷贝构造
	Date d2 = d1;
	Date d3(d1);

	Date d4(2024,5,30);
	d1 = d4;//此时是什么?赋值拷贝

	d1 = d2 = d4; //连续赋值
	return 0;
}

很多人也都建议使用引用返回:

在这里插入图片描述

那传值返回与传引用返回有什么区别呢?效率上的区别
看下面的func函数:
在这里插入图片描述
那有没有什么方式让它不发生拷贝构造呢?传引用返回
下面代码没有发生拷贝构造
在这里插入图片描述

但此时会有问题,确实减少了拷贝,但是引用实际上就是给d取了一个别名,二者都指向d,但是d都析构了,此时返回了临时变量的地址,类似于C中的野指针了。

二者地址打印出来是一样的。
在这里插入图片描述

总结一下:
若返回对象是一个局部对象或临时对象,出来当前函数的作用域就析构销毁了,就不能使用引用返回,用引用返回是存在风险的,引用对象在那个函数的栈帧中已经销毁了。

即:

  • 出了作用域,返回对象还没有析构,那就可以传引用放回,减少拷贝
    a、返回对象声明周期到了,会析构,传值返回
    b、返回对象声明周期没到,不会析构,传引用返回

对于最开始写的日期的赋值重载,this在operator的栈帧上,但是*this在main函数的栈帧中,返回对象没有析构,因此可以使用引用返回。

5.2.3检测是否自己给自己赋值

为了防止有人自己给自己赋值,赋值前可以判断一下,提高效率,避免不必要的操作。
在这里插入图片描述

5.2.4注意返回值

返回*this :要复合连续赋值的含义

5.2.5重载成类的成员函数

赋值运算符只能重载成类的成员函数不能重载成全局函数
在这里插入图片描述

5.2.6默认赋值运算符重载

跟拷贝构造类似,用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。
注意:

  • 内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值
  • 如果类中未涉及到资源管理,赋值运算符是否实现都可以;一旦涉及到资源管理则必须要实现。

5.3前置++与后置++重载

我们知道,前置++与后置++重载以后,二者是一样的,没有办法区分。我们的祖师爷就给后置++强行增加了一个int类型的形参该形参不需要写参数名,调用函数参数不需要传(编译器自动传)或者 传递任何数都可,这个参数仅仅为了跟前置区分,不会使用。
在这里插入图片描述
一般会这样写:

在这里插入图片描述

5.4运算符重载拓展

我们之前要想打印类中的成员变量,都是写了一个Print函数

在这里插入图片描述

那我们能不能使用C++标准库中的cout与cin输出呢?

在这里插入图片描述
很显然,正常情况下是不可以的。
对于内置类型我们可以直接使用是因为C++标准库中已经写好了,流插入与流提取也是函数重载。
在这里插入图片描述

	int i = 10;
	cout << i;
	//上面的代码本质上转换为下面的
	cout.operator<<(i);

cout与cin可以自动识别类型,本质上是因为这些流插入重载构成函数重载。

那自定义类型要想写,那我们就得自己写函数重载,怎么写呢?如下:
在这里插入图片描述
此时我们发现依然无法调用,为什么呢?

如果我们自己调用,那就应该按下面的方式写。
你是我d1的成员函数嘛

void Test1()
{
	Date d1(2024, 5, 26);
	Date d2(1982, 6, 6);

	//cout << d1;
	//cout << d2;
	//自己写调用
	d1.operator<<(cout);
	d2.operator<<(cout);
}

所以我们应该按下面的方式写:
在这里插入图片描述

这样写又非常的奇怪,那我们能不能让它的顺序颠倒一下呢?
在这里插入图片描述

所以,operator<<想重载为成员函数可以,但是用起来不符合正常逻辑,不建议这样做,建议重载为全局函数。
在这里插入图片描述

6.const成员函数

有时候我们需要把对象设置为只读的,但是这时候就会存在一些问题。
在这里插入图片描述

因此,我们的祖师爷就规定在函数的后面加const,看起来很怪,但确实也没有什么好的办法了

在这里插入图片描述

7.取地址及const取地址操作符重载

这两个默认成员函数一般不用重新定义 ,编译器默认会生成。

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

这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

本地源码方式部署启动MaxKB知识库问答系统,一篇文章搞定!

MaxKB 是一款基于 LLM 大语言模型的知识库问答系统。MaxKB Max Knowledge Base&#xff0c;旨在成为企业的最强大脑。 开箱即用&#xff1a;支持直接上传文档、自动爬取在线文档&#xff0c;支持文本自动拆分、向量化、RAG&#xff08;检索增强生成&#xff09;&#xff0c;智…

补天计划 | 多款产品免费试用!

HVV时期网络安全攻防对抗的不对称性特别明显&#xff0c;红方会准备极为丰富的武器库与全方位的攻击手段。对蓝方而言&#xff0c;只要防线中存在任意盲区或短板便可能导致整条防线被绕过&#xff0c;顷刻间自己的工作成果化为安全对抗领域“马奇诺防线”。 攻防对抗中是长时间…

VSCode自动生成代码片段

1. 代码片段配置入口 输入&#xff1a;snipp 选择 Configure User Snippets 然后再选择 New Global Snippets file 输入 新建文件名称&#xff0c;然后按回车键。 2. 编辑代码模板 文件头和函数头模板&#xff1a; {"FileHeader":{"scope": "…

OrangePi AIpro 性能测试以及使用体验

OrangePi AIpro 性能测试以及使用体验 1. 介绍 OrangePi AIpro(8T)采用昇腾AI技术路线。 具体为4核64位处理器AI处理器&#xff0c;集成图形处理器&#xff0c;支持8TOPS AI算力拥有8GB/16GB LPDDR4X&#xff0c;可以外接32GB/64GB/128GB/256GB eMMC模块&#xff0c;支持双4…

如果一个开发初学者从今天开始,他们应该学习什么?

What should a beginner developer learn if they were to start today? by Scott Hanselman 如果从今天才开始学习&#xff0c;新手开发者要学习什么&#xff1f; 新的开发人员今天应该从哪里开始&#xff1f; 他们应该学习什么来为自己的职业生涯做好准备&#xff1f;Sco…

PWN入坑指南

CTF的PWN题想必是很多小伙伴心里的痛&#xff0c;大多小伙伴不知道PWN该如何入门&#xff0c;不知道该如何系统性学习 0x01开篇介绍 PWN 是一个黑客语法的俚语词 &#xff0c;是指攻破设备或者系统 。发音类似"砰"&#xff0c;对黑客而言&#xff0c;这就是成功实施黑…

从多站点到多活,XEOS 对象数据容灾能力再提升

近日&#xff0c; XSKY SDS V6.4 新版本发布&#xff0c;其中 XEOS V6.4 全新升级并完善了统一命名空间功能&#xff0c;更进一步增强和完善了异地容灾方案&#xff0c;配合强一致代理读&#xff0c;可以实现异地多活&#xff1b;同时大幅降低管理复杂度&#xff0c;有效降低容…

K8S认证|CKA题库+答案| 13. sidecar 代理容器日志

目录 13、使用 sidecar 代理容器日志 CKA v1.29.0模拟系统 下载试用 题目&#xff1a; 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、生成yaml文件 3&#xff09;、官网找模板 4&#xff09;、编辑yaml文件 5&#xff09;、应用yaml文件 ​6&…

CyberDAO全国行第三站·西安圆满落幕

CyberDAO全国行第三站于2024年5月27日在西安顺利召开。以聚势启新&#xff0c;聚焦Web3新机遇&#xff0c;开启Web3财富密码为本次会议的思想路线&#xff0c;汇聚了大批Web3爱好者齐聚古城西安。CyberDAO致力于帮助更多Web3爱好者捕获行业价值。 以圆桌论坛《机遇拥抱Web3》拉…

三、Ollama导入大模型(.Net8+SemanticKernel+Ollama)本地运行自己的大模型

Ollama导入大模型 一、导入Ollama大模型1、使用run命令2、使用Modelfile方式 二、导入自定义大模型&#xff08;Ollama官网以外的大模型&#xff09;三、使用OpenWebUI导入大模型 Ollama可以导入官方提供的大模型&#xff0c;也可以导入huggingface上的自定义大模型&#xff08…

深入Java:JSON解析与操作的艺术

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 一、初识JSON&#xff1a;数据格式的优雅舞者 在现代Web开发中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;以其轻量级和易于阅读的特点成为了数据交换的首选格式。它基于JavaScript的一个…

长安链使用Golang编写智能合约教程(二)

本篇说的是长安链2.3.的版本的智能合约&#xff0c;虽然不知道两者有什么区别&#xff0c;但是编译器区分。 教程三会写一些&#xff0c;其他比较常用SDK方法的解释和使用方法 编写前的注意事项&#xff1a; 1、运行一条带有Doker_GoVM的链 2、建议直接用官方的在线IDE去写合…

2024-2030数据集成成熟度曲线(一)

作者 | 郭炜 导读&#xff1a;最新发布的《技术成熟度曲线2024》全面评估数据集成技术架构的7个维度&#xff0c;包括技术成熟度、技术难度、业务价值、技术成熟周期、管理协作难度、大模型结合等评估维度&#xff0c;报告篇幅较长&#xff0c;我们将报告分为3篇系列文章&#…

企业微信H5授权登录

在企业中如果需要在打开的网页里面携带用户的身份信息&#xff0c;第一步需要获取code参数 如何实现企业微信H5获取当前用户信息即accessToken&#xff1f; 1.在应用管理--》创建应用 2.创建好应用&#xff0c;点击应用主页-》设置-》网页-》将授权链接填上去 官方文档可以看…

配餐中的红酒温度控制与口感体验

在红酒配餐中&#xff0c;温度控制是影响口感体验的重要因素之一。合适的温度可以释放红酒的香气和风味&#xff0c;使酒体更加圆润和丰富。云仓酒庄雷盛红酒以其卓着的品质和与众不同的口感&#xff0c;成为了红酒爱好者们的首要选择品牌。下面将介绍如何通过温度控制提升红酒…

哈夫曼树,哈夫曼编码和线索二叉树

前言 在数据压缩中,如电脑中的压缩软件,哈夫曼编码应用比较广泛,因此被称作最优二叉树。下面时哈夫曼树的一些定义。 哈夫曼树 定义 代码 下面时哈夫曼树的初始化和创建: #include "stdio.h"#define MAXSIZE 5 typedef struct {int weigth;int parent, lchi…

2024年最新实景无人自动直播软件揭秘:降低成本,提升效率

在信息技术迅猛发展的时代&#xff0c;实景无人自动直播软件成为了各行各业的关注焦点。随着2024年的到来&#xff0c;最新的实景无人自动直播软件将以其降低成本、提升效率的特点引领行业。本文将揭秘这一创新软件的工作原理&#xff0c;并探讨其在各个领域的应用&#xff0c;…

常用图像分类预训练模型大小及准确度比较

近年来&#xff0c;深度学习技术的发展使得图像分类任务变得越来越容易。预训练模型的出现更是使得图像分类任务变得更加简单和高效。然而&#xff0c;随着预训练模型的数量和大小的增加&#xff0c;我们需要了解每个模型的特点和优缺点&#xff0c;以便更好地选择和使用它们。…

国内半导体龙头企业的自动化转型之旅

在当今高速发展的科技时代&#xff0c;半导体行业正迎来前所未有的挑战与机遇。位于此浪潮前端的&#xff0c;是国内一家领先的半导体集成电路封装测试企业。凭借其规模和创新实力&#xff0c;该公司不仅在国内市场名列前茅&#xff0c;更是在全球半导体行业中占据了一席之地。…

.DFS.

DFS 全称为Depth First Search&#xff0c;中文称为深度优先搜索。 这是一种用于遍历或搜索树或图的算法&#xff0c;其思想是: 沿着每一条可能的路径一个节点一个节点地往下搜索&#xff0c; 直到路径的终点&#xff0c;然后再回溯&#xff0c;直到所有路径搜索完为止。 DFS俗…