【c++】——类和对象(中)——默认成员函数(上)

news2024/11/25 22:26:55
【学习目标】
  • 1. 类的6个默认成员函数
  • 2. 构造函数
  • 3. 析构函数
  • 4. 拷贝构造函数

目录

一.类的6个默认成员函数

二. 构造函数

2.1 概念

2.2.特性

三.析构函数

3.1.概念

3.2 特性

四.拷贝构造函数

4.1.概念

4.2.特性


一.类的6个默认成员函数

如果一个类中什么成员都没有,简称为空类。
空类中真的什么都没有吗?
并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成函数。
默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
class Date {};

 


二. 构造函数

2.1 概念

class Date
{
public:
	void init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	void print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1.init(2023, 11, 05);
	d1.print();

	return 0;
}

对于 Date 类,可以通过 Init 公有方法给对象设置日期,但如果每次创建对象时都调用该方法设置信息,未免 有点麻烦,那能否在对象创建时,就将信息设置进去呢?
构造函数是一个特殊的成员函数,
1.名字与类名相同,
2.创建类类型对象时由编译器自动调用,以保证每个数据成 员都有 一个合适的初始值
3.在对象整个生命周期内只调用一次。  

2.2.特性

构造函数 是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造
构造函数的主要任务 并不是开 空间创建对象,而是 初始化对象
特征如下:
  • 1. 函数名与类名相同。
  • 2. 无返回值。
  • 3. 对象实例化时编译器自动调用对应的构造函数。
  • 4. 构造函数可以重载。
  • 5. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。

构造函数可以分成2类——无参构造函数和有参构造函数

class Date
{
public:
	/*void init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}*/
	// 1.无参构造函数
	Date()
	{}
	// 2.有参构造函数
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	void print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1; // 调用无参构造函数
	Date d2(2015, 1, 1); // 调用带参的构造函数
	d1.print();
	d2.print();
	return 0;
}

注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则

就成了函数声明 以下代码的函数:声明了d3函数,该函数无参,返回一个日期类型的对象

Date d3()不是很惯用的函数声明,我换种形式 int func(),这样看是不是更清楚了,这就是相当于无参函数的声明。int func(void).
以上的四点特性我已经一一列举展示出来,接下来第5点。

特性5:

5. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
  • 类中显式定义构造函数,就是显示上面的代码段,编译器就不用给出帮助,因为自己传参了。
  • 类中没有显示定义构造函数C++编译器会自动生成一个无参的默认构造函数。然后给出的成员变量的值都是随机值。

我们看一下这下面的代码段,为什么显示“没有合适的默认构造函数可用”??

错误原因:在Date类中定义了其他构造函数,那么,编译器不会为你创建默认构造函数;然而,在编译器调用Date的默认构造函数时,就会找不到,d1是无参的对象,而上面的默认构造函数是存在参数的,所以编译器显示没有合适的默认构造函数可用。

解决方法:加入默认构造函数,与之匹配。

如果Date创建的对象d1传参和上面的构造函数参数个数类型匹配,就说明找到合适的默认构造函数可用,否则都得创建一个与之对应参数个数类型的默认构造函数即可。

特性6: 

6. 关于编译器生成的默认成员函数,很多童鞋会有疑惑:不实现构造函数的情况下,编译器会生成默认的 构造函数。但是看起来默认构造函数又没什么用?d对象调用了编译器生成的默认构造函数,但是d对象 _year/_month/_day,依旧是随机值。也就说在这里编译器生成的默认构造函数并没有什么用??
解答: C++把类型分成内置类型(基本类型)和自定义类型。
  • 内置类型:  就是语言提供的数据类型,如: int/char...,
  • 自定义类型:  就是我们使用class/struct/union等自己定义的类型,
看看下面的程序,就会发现编译器生成默认的构造函数会对自定类型成员_t调用的它的默认成员函数(构造函数)
大家看这里的Date类与上面那个有什么区别,是不是它的成员变量里既有内置类型又有自定义类型啊。但是我们现在并没有给Date类写构造函数,那我们在main函数里直接拿Date去创建一个对象,它自然就会去调用编译器自动生成的构造函数,那内置类型不做处理,我们不是还有一个自定义类型Time _t;呢,我们说对于自定义类型,编译器会自动去调用它对应的默认构造函数。
那我们在Time 类的默认构造函数里面故意加了一个打印:
这里很明显编译器对于自定义类型成员_t去调用构造函数。
注意: C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即: 内置类型成员变量在类中声明时 可以给默认值.
这样如果我们不写构造函数,内置类型的初始化就会按给定的缺省值进行初始化。
这里我需要强调一下,自定义类型和内置类型的区别:系统会默认给内置类型初始化一个随机值,但是随机值是没有意义的,虽然后来打了补丁可以给缺省值,但是我们未来还会用到更多的类型例如自定义类型,这时我们就需要自定义类型,因此自定义所构造的构造函数可以更好的帮助我们进行初始化。

特性7: 

7. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。
注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。
我们上面的特性说了,只能有一个默认构造函数,这里出现了俩个默认构造函数,所以就导致了对重载函数的调用不明确,因为不知道到底调哪个默认构造函数。
这里我们要特别区分俩个名词:默认成员函数和默认构造函数
  • 默认成员函数:任何类在什么都不写时,编译器会自动生成以下6个默认成函数。
  • 默认构造函数:类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数。

三.析构函数

我们在之前数据结构的学习中,在学到栈的时候,有一个与栈相关的非常经典的题目——括号匹配问题。

来看一下我们C语言写出来的代码,我们进行判断之后,需要return的地方可能有好几处,但是呢,每次return之前,其实最好都要去调用一下StackDestroy把我们动态开辟的空间给销毁一下,但是我们可能很容易会忘掉导致内存泄漏。

那现在我们学了C++,有没有什么好的办法可以帮助我们解决这个问题呢?

可不可以像上面的构造函数自动初始化一样自动对对象中的资源进行清理呢?

那当然是有的,就是我们接下来要学习的析构函数。先了解概率吧。

3.1.概念

通过前面构造函数的学习,我们知道一个对象是怎么来的,那一个对象又是怎么没呢的?
—— 析构函数: 与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作

3.2 特性

析构函数 是特殊的成员函数,其 特征如下:
  • 1. 析构函数名是在类名前加上字符 ~。(~就相当于运算符里面的按位取反操作符)
  • 2. 无参数无返回值类型。

  • 3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。

注意:析构函数不能重载

  • 4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。

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

特性5:

5. 关于编译器自动生成的析构函数,是否会完成一些事情呢?
下面的程序我们会看到,编译器生成的默认析构函数,对自定类型成员调用它的析构函数。
class Time
{
public:
	~Time()
	{
		cout << "~Time()" << endl;
	}
private:
		int _hour;
	int _minute;
	int _second;
};
class Date
{
private:
	// 基本类型(内置类型)
	int _year = 1970;
	int _month = 1;
	int _day = 1;
	// 自定义类型
	Time _t;
};
int main()
{
	Date d;
	return 0;
}

这里我们没有给Date显式定义析构函数,那d声明周期结束时,就会调用编译器自己生成的默认析构函数,那里面的内置类型不做处理,当然也不用处理,关键在于自定义类Time _t;申请的资源需要清理,那我们看编译器自己生成的默认析构函数会不会调用Time _t类的析构函数:

这是上面代码的运行结果。显然是调用了。

这时候我们就应该想一个问题了?
——在main方法中根本没有直接创建Time类的对象,为什么最后会调用Time类的析构函数?
因为:main方法中创建了Date对象d,而d中包含4个成员变量,其中_year, _month, _day三个是内置类型成员,销毁时不需要资源清理,最后系统直接将其内存回收即可
而_t是Time类对象,所以在 d销毁时,要将其内部包含的Time类的_t对象销毁,所以要调用Time类的析构函数。但是:main函数中不能直接调用Time类的析构函数,实际要释放的是Date类对象,所以编译器会调用Date类的析构函数,而Date没有显式提供,则编译器会给Date类生成一个默认的析构函数,目的是在其内部调用Time 类的析构函数,即当Date对象销毁时,要保证其内部每个自定义对象都可以正确销毁,main函数中并没有直接调用Time类析构函数,而是显式调用编译器为Date类生成的默认析构函数。
注意:创建哪个类的对象则调用该类的析构函数,销毁那个类的对象则调用该类的析构函数。

特性6:

6. 如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如Date类;有资源申请时,一定要写,否则会造成资源泄漏,比如Stack类

四.拷贝构造函数

4.1.概念

在现实生活中,可能存在一个与你一样的自己,我们称其为双胞胎。
那在创建对象时,可否创建一个与已存在对象一某一样的新对象呢?
拷贝构造函数 只有单个形参 ,该形参是对本 类类型对象的引用 ( 一般常用 const 修饰 ) ,在用 已存在的类类型 对象创建新对象时由编译器自动调用

4.2.特性

拷贝构造函数也是特殊的成员函数, 特征如下:
  • 1. 拷贝构造函数是构造函数的一个重载形式

因为我们刚才上面说了嘛,它的作用其实也是用来初始化对象的,只不过参数类型指定了是我们当前类的类型嘛。所以它算是构造函数的一种重载形式。

  • 2. 拷贝构造函数的参数只有一个必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。

我们按照上面形式传参,会导致显示一个错误编译,没有运行就错了。

那相信大家刚才也注意到上面的概念了,在拷贝构造函数的概念中其实就指明了说它的参数类型应该是类对象的引用。

确实,我们这样修改之后就可以了。

2. 拷贝构造函数的参数只有一个必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。

结合下面这张图给大家解释一下:
ps:图中还在形参前加了const,大家可以先不管,后面会解释。

大家想一下,首先我们这里是用已有的类对象去创建一个相同的新对象(类对象的拷贝),所以会调用拷贝构造函数,那要调用函数是不是要先传参啊,而传值调用传的是啥(形参是实参的一份临时拷贝),是不是传的实参的拷贝,那要拷贝实参,是不是又是一个类对象的拷贝啊,那既然是类对象的拷贝,就又要调用拷贝构造函数,那就又需要传参,一传参就会再次调用拷贝构造函数,那这样是不是就陷入一个死递归了。

直接用“=”也可以,这样也是拷贝构造。

上面一开始拷贝构造函数的概念中说它的形参一般用const修饰:
为什么要加个const呢?
其实很容易理解,大家想形参d是用来干嘛的, 是用来初始化我们新创建的对象的,那我们肯定不希望形参d被修改,所以加个const修饰
这样我们如果不小心写反了啥的是不是就直接报错了。

另外,加const还有什么好处呢?

大家想,如果我们不加const,但传过来的参数是const修饰的,这样的话是不是根本就接收不了啊,这个问题我们之前也讲了,是不是属于权限放大了,是不行的。但是如果我们加了const,传过来的不管是否加const,是不是都可以接收啊。

特性3:

3. 若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成 拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
🆗,那我们上面说了拷贝构造函数是构造函数的一种重载形式,那其实就也属于是构造函数了,那构造函数我们不写的话编译器不是会自动生成嘛,那拷贝构造函数是不是也具有这样的特性呢?
是的,对于拷贝构造函数来说,若未显式定义,编译器也会生成默认的拷贝构造函数。
我们刚才不是对Date类实现了一个拷贝构造函数嘛,先我们现在把它屏蔽调:
class Date
{
public:
	//构造函数
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	
	//拷贝构造函数
	/*Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}*/

void Print()
{
	cout << _year << "-" << _month << "-" << _day << endl;
}
private:
	int _year;
	int _month;
		int _day;
};
int main()
{
	Date d1;
	d1.Print();
	Date d2(d1);
	d2.Print();
	Date d3 = d1;
	d3.Print();

	return 0;
}

注意:在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。

那既然编译器自动生成的拷贝构造函数就可以帮助我们完成类对象的拷贝了,那我们还需要自己写吗?

特性4:

那为了解决这个问题,我们再来看这样一个类:
4. 编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗?当然像日期 类这样的类是没必要的。那么下面的类呢?验证一下试试?
typedef int DataType;
class Stack
{
public:
	Stack(int capacity = 4)
	{
		_array = (DataType*)malloc(sizeof(DataType) * capacity);
		if (NULL == _array)
		{
			perror("malloc申请空间失败!!!");
			return;
		}
		_capacity = capacity;
		_size = 0;
	}
	void Push(DataType data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	// 其他方法...
	~Stack()
	{
		cout << "~Stack" << endl;
		free(_array);
		_array = NULL;
		_capacity = 0;
		_size = 0;
		
	}
private:
	DataType* _array;
	int _capacity;
	int _size;
};

还是我们之前用过的这个栈Stack类,大家看它的成员变量是不是也都是内置类型啊,前面提到过指针也属于内置类型嘛。

那对于Stack这个类,我们也是没写拷贝构造函数的,那编译器自动生成的能不能完成下面这样的拷贝呢?

int main()
{
	Stack s1;
	s1.Push(1);
	s1.Push(2);
	s1.Push(3);

	Stack s2(s1);
	return 0;
}

为什么会这样呢,刚才Date类不也都是内置类型,为啥就没事呢? 

大家有没有注意到我们上面的特性3,后面的一句话是:
默认的拷贝构造函数 拷贝对象 按内存存储字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。在这里其实就是对逐个成员变量依次进行拷贝,里面存的是啥就把啥拷过去。

那原因其实就出现在这里,我们来对比一下Date和Stack这两个类进行的拷贝:
首先对于Date类来说,进行这样的浅拷贝有没有问题啊。

是不是没问题啊,一共12个字节的内容,直接拷贝过去就行了嘛

但是,对于Stack类来说呢?

我们还是这样进行浅拷贝的话:

我们有没有想过,_array指向的空间在堆区malloc(是在堆区),在销毁对象的时候要销毁对象内部的成员变量,在成员变量中有一个变量是指向该堆区内存的指针,因此每销毁一个对象就要销毁对应的内存地址,而浅拷贝会导致被销毁的两个对象中的那两个成员指针变量指向同一块内存,从而导致该内存被销毁两次。

比如一个文件f1里面包含了各种资料,我们需要再继续创建一个不同名文件f2但是文件里面的内容相同,然后删除这个原本文件f1之前,我们是不是需要拷贝这个文件,然后才能删除。我们想想,内容是在不同的文件里面的,虽然是相同的,我们销毁f1文件里面的内容,是不是销毁f1文件,销毁f2文件里面的内容,是不是销毁f1和f2文件内容是占据不同的文件。

这就是深拷贝,就是将内容构造拷贝时,_array需要开一快同样的大小空间。

这样对两个对象进行操作就不会互相影响了。

Stack(const Stack& st)
	{
		_array = (DataType*)malloc(sizeof(DataType) * st._capacity);
		if (NULL == _array)
		{
			perror("malloc申请空间失败!!!");
			exit(-1);
		}
		memcpy(_array, st._array, sizeof(DataType) * st._size);
		_capacity = st._capacity;
		_size = st._size;
	}

没有问题了。

注意: 类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请时,则拷贝构 造函数是一定要写的,否则就是浅拷贝。
总结:在编译器生成的默认拷贝构造函数中,内置类型是按照浅拷贝(值拷贝)进行拷贝的,而自定义类型是调用其对应的拷贝构造函数完成拷贝的。

特性5:

5. 拷贝构造函数典型调用场景:
  • 使用已存在对象创建新对象
  • 函数参数类型为类类型对象
  • 函数返回值类型为类类型对象
为了提高程序效率,一般对象传参时,尽量使用引用类型(减少拷贝),返回时根据实际场景,能用引用尽量使用引用。

考研,还是就业?

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

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

相关文章

解决 SSLError: HTTPSConnectionPool(host=‘huggingface.co‘, port=443)

看我的回答&#xff1a; https://github.com/huggingface/transformers/issues/17611#issuecomment-1794486960 能问这个问题的都是网络不太好的&#xff0c;你懂的&#xff0c;所以答案全是解决网络的。 得益于这个回答&#xff1a;#17611 (comment) 看了一下代码&#xf…

Apache Doris (五十三): Doris Join类型 - Shuffle Join

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 目录 1. shuffle Join的原理

学信息系统项目管理师第4版系统36_结语

1. 尘埃落定 10月28日首考&#xff0c;到11月5日结束&#xff0c;尘埃落定&#xff0c;尘归尘、土归土了。 软考机考第一次吃螃蟹&#xff0c;几家欢喜几家愁&#xff0c;高项的选择题和案例题反馈简单&#xff0c;原书原文的考法&#xff0c;不过属于犄角旮旯那种。 中级则普…

GPT-4V:AI在教育领域的应用

OpenAI于9月25日发布了最新的GPT-4V模型&#xff0c;为ChatGPT引入了语音和图像功能&#xff0c;为用户提供更多元化的使用方式。这次更新将为用户带来更便捷、直观的交互体验&#xff0c;用户可以直接拍照上传并针对照片内容提出问题。OpenAI的最终目标是构建安全、有益的人工…

WindowsServer2019-搭建FTP服务器

这里写自定义目录标题 一、基础配置IP地址安装FTP服务检查连通性Windows10连接FTP服务 二、了解和使用FTP具体模块及其配置1、FTP IP地址和域限制2、FTP SSL设置3、FTP当前会话4、FTP防火墙5、FTP目录浏览6、FTP请求筛选7、FTP日志8、FTP身份验证9、FTP授权规则10、FTP消息11、…

数据结构(五):哈希表及面试常考的算法

一、哈希表介绍 1、定义 哈希表&#xff0c;也叫散列表&#xff0c;是根据关键码和值 (key和value) 直接进行访问的数据结构&#xff0c;通过key和value来映射到集合中的一个位置&#xff0c;这样就可以很快找到集合中的对应元素。例如&#xff0c;下列键(key)为人名&#xf…

5、Python中的变量和表达式:变量的定义、赋值和数据类型转换

文章目录 Python中的变量和表达式:变量的定义、赋值和数据类型转换变量的定义变量的赋值数据类型转换注意事项表达式总结Python中的变量和表达式:变量的定义、赋值和数据类型转换 Python是一种高级编程语言,以其简洁明了的语法和强大的功能而闻名。在Python编程中,变量和表…

docker安装达梦数据库镜像并初始化实例设置数据库大小写不敏感

全文参考文章Docker - 通过容器安装部署达梦数据库教程 以及docker安装达梦V8数据库 UTF-8及大小写敏感问题 一、安装部署达梦数据库 下载完成之后使用FileZilla上传到服务器上面 启动命令 创建dm8的容器并设置大小写不敏感运行 docker run -d -p 5236:5236 \ --restartalwa…

链式前向星模板

建稠密图可以用邻接矩阵&#xff0c;但稀疏图再用邻接矩阵就很浪费空间了&#xff0c;有可能会爆空间复杂度。 可以用邻接表来实现邻接表建图&#xff0c;两种方法&#xff1a;1.链表 2.链式前向行 只讲第二种&#xff0c;比较常用简洁 链式前向星模板 #define IOS ios::syn…

详解vue3的ref和reactive

目录 Vue3是目前前端领域最受欢迎的JavaScript框架之一&#xff0c;它的核心是响应式数据系统。因此&#xff0c;Vue3的ref和reactive成为了Vue3的核心特性之一。通过使用这两个特性&#xff0c;我们能够轻松地构建出高效、可维护的Vue3应用程序。在本文中&#xff0c;我们将详…

CoTTA:连续的测试时域自适应方法

文章信息 论文题目为《Continual Test-Time Domain Adaptation》&#xff0c;该文于2022年发表于Conference on Computer Vision and Pattern Recognition (CVPR)会议上。文章提出了一种持续的测试时域自适应方法&#xff08;CoTTA&#xff09;&#xff0c;旨在应对非稳态和不断…

本周三商店更新:多款套装下线,四款升级武器带异色皮肤返厂

本周三将迎来26.2版本更新与11商店大更新&#xff0c;版本更新可点击26.2版本更新公告进行查看&#xff0c;这里不一一赘述了&#xff0c;下面大概罗列一下商店更新&#xff0c;有皮肤下架&#xff0c;大家还能趁最后时间入手&#xff0c;最重要的是四款升级武器返厂咯。 危险玩…

shell脚本入门之【变量的定义】

&#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《shell》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一定基础的程序员&#xff0c;…

vue.js实现科室无限层选中和回显

一、效果展示&#xff1a; 展示可选层级 查看选中的值 二、实现&#xff1a; <el-form-item label"相关科室:" prop"orgId"><el-cascaderpopper-class"cascader-my":options"orgOptions":show-all-levels"false"…

文献管理软件Zotero之入门篇(1)

文章目录 0、前言1、下载安装1.1、下载安装主程序1.2、下载安装浏览器插件 2、给Zotero添加插件以实现更多快捷功能2.1、插件安装方式2.2、插件获取方式2.2.1、直接在官网插件也下载2.2.2、在Zotero中文社区插件页下载 3、总结 0、前言 一直以来想找一个文献管理帮手&#xff…

二进制代码反汇编逆向工具:IDA Pro(WinMac)v7.7 汉化版

IDA Pro是一款交互式的、可编程的、可扩展的、多处理器的、交叉Windows或Linux WinCE MacOS平台主机来分析程序。它被公认为最好的花钱可以买到的逆向工程利器&#xff0c;已经成为事实上的分析敌意代码的标准并让其自身迅速成为攻击研究领域的重要工具。 IDA Pro的特点主要包括…

海康Visionmaster-全局脚本:通过全局脚本获取通讯输 入的参数并赋值给全局变量

全局脚本根据外部通讯输入的数值赋值给全局变量&#xff0c;实现输入与全局变量之间的数值绑定。&#xff08;一般应用于定位、标定等需要外界物理值的场景)。 第一步&#xff0c;在 vm 通讯管理中设置好通讯设备&#xff0c;连接 第二步&#xff0c;根据通讯设备、接收的信息…

基于CMT2119A 无线发射芯片的物联网技术研究

随着物联网技术的快速发展&#xff0c;无线通信设备的需求也越来越大。CMT2119A无线发射芯片作为一种先进的芯片技术&#xff0c;被广泛应用于物联网中。本文通过对CMT2119A无线发射芯片的研究&#xff0c;探讨了其在物联网技术中的应用&#xff0c;分析了其特点和优势&#xf…

【Rust 日报】2023-11-05 xAI使用Rust

马斯克xAI正式使用Rust 在深度学习研究的前沿&#xff0c;必须像构建数据集和学习算法一样谨慎地构建可靠的基础设施。为了创建 Grok&#xff08;一个类ChatGPT的产品&#xff09;&#xff0c;xAI构建了一个基于 Kubernetes、Rust 和 JAX 的自定义训练和推理套件。 xAI认为&…

【Linux】拓展:进程管理常见的7大问题

目录 一、如何判断一个程序是单线程还是多线程 二、僵尸进程是什么&#xff0c;有什么危害&#xff0c;如何解决 三、如何找回删掉的文件 四、删除文件以后&#xff0c;空间不释放 五、遇到一个病毒&#xff08;如死循环病毒&#xff09;&#xff0c;解决思路 六、机器开机…