《类和对象(中)》
引言:
上次我们主要学习了类的相关知识,今天我们就来学习类和对象(中),今天也会用到之前学习过的东西,可以说是前面知识的结合,较前面会难一点(打个预防针)。
一:类的默认成员函数
通俗来说,默认成员函数就是我们没有自己写,但是编译器也会自动生成的一种函数,一般来说,一个类有六
个默认成员函数,但是最后的两个:取地址重载不是那么重要,只需简单了解即可。其实C++11以后还会增加两个默认成员函数,移动构造和移动赋值,这个我们后面才会学到。默认成员函数很重要,也比较复杂,我们可以从以下两个方面去学习:
- 我们不写时,编译器默认生成的函数行为是什么,是否满足我们的需求。
- 编译器默认生成的函数不满足我们的需求,我们需要自己实现,那么如何自己实现?
下面我们就来重点学习前面这四个默认成员函数。
二:构造函数
构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象(我们常使用的局部对象是栈帧创建时,空间就开好了),而是对象实例化时初始化对象。构造函数的本质是要替代我们以前Stack
和Date
类中写的Init
函数的功能,构造函数自动调用的特点就完美的替代的了Init
。
构造函数的特点:
- 函数名与类名相同。
- 无返回值。(什么都不用写,不用抬杠,祖师爷这么规定的)
- 对象实例化时系统会自动调用对应的构造函数。
- 构造函数可以重载。
- 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
- 无参构造函数、全缺省构造函数、我们不写构造时编译器默认生成的构造函数,都叫做默认构造函数。但是这三个函数有且只有一个存在,不能同时存在。无参构造函数和全缺省构造函数虽然构成函数重载,但是调用时会存在歧义。要注意很多同学会认为默认构造函数是编译器默认生成那个叫默认构造,实际上无参构造函数、全缺省构造函数也是默认构造,总结一下就是:不传实参就可以调用的构造就叫默认构造。
- 我们不写,编译器默认生成的构造,对内置类型成员变量的初始化没有要求,也就是说是是否初始化是不确定的,看编译器。对于自定义类型成员变量,要求调用这个成员变量的默认构造函数初始化。如果这个成员变量,没有默认构造函数,那么就会报错,我们要初始化这个成员变量,需要用初始化列表才能解决,初始化列表,我们下个章节才会学。
说明:C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的原生数据类型,如:int/char/double/指针
等,自定义类型就是我们使用class/struct
等关键字自己定义的类型。
1. 构造函数形式
2. 构造函数的自动调用
解读:这里我们在实现的构造函数里面加上了一句打印语句来判断构造函数是否被调用,通过运行程序我们可以看到构造函数是自动调用的,并且通过打印这个日期也是可以看到初始化正常。
3. 构造函数重载
解读:这里我们的两个构造函数一个带参一个不带参,构成了函数重载,我们在实例化对象的时候,编译器就会自动调用对应的构造函数,这里我们通过加上输出语句也可以看到编译器确实是自动调用了相应的构造函数。这里需要注意的一个点就是,当我们想调用不带参的那个构造函数时,这里是不用加()
的,为了避免与函数声明产生冲突。
但是这里完全可以写成一个全缺省的形式,这样只需要一个就能满足需求。
4. 内置类型和自定义类型调用构造函数的区别
这里我们利用之前实现的栈来和日期类进行一个对比:
解读:明显可以看到,对于内置类型的Date
,编译器生成的默认构造函数并没有对其成员进行初始化,但是对于自定义类型Mystack
中的 st1
和st2
,编译器都对其进行了初始化。
5. 小结:
大多数的类,我们都需要自己来实现构造函数,但是对于少数的自定义类不需要自己来实现构造函数,比如Mystack
可以自己使用默认生成的构造函数。
三:析构函数
析构函数与构造函数功能相反,析构函数不是完成对对象本身的销毁,比如局部对象是存在栈帧的,函数结束栈帧销毁,他就释放了,不需要我们管,C++规定对象在销毁时会自动调用析构函数,完成对象中资源的清理释放工作。析构函数的功能类比我们之前Stack
实现的Destroy
功能,而像Date
没有Destroy
,其实就是没有资源需要释放,所以严格说Date
是不需要析构函数的。
析构函数的特点:
- 析构函数名是在类名前加上字符
~
。 - 无参数无返回值。(这里跟构造类似,也不需要加
void
) - 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。
- 对象生命周期结束时,系统会自动调用析构函数。
- 跟构造函数类似,我们不显示写的话,编译器自动生成的析构函数对内置类型成员不做处理,自定义类型成员会调用他的析构函数。
- 还需要注意的是即使我们显示写析构函数,对于定义类型成员也会调用他的析构,也就是说自定义类型成员无论什么情况都会自动调用析构函数。
- 如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,如
Date
;如果默认生成的析构就可以用,也就不需要显示写析构,如MyQueue
;但是有资源申请时,一定要自己写析构,否则会造成资源泄漏,如Stack
。 - 一个局部域的多个对象,C++规定后定义的先析构。
1. 析构函数形式
2. 析构函数的自动调用
解读:这里我们在析构函数里面加上了一个打印语句来验证编译器是否自动调用了的析构函数,通过运行程序可以看到在运行结束后编译器确实自动调用了析构函数。
3. 内置类型和自定义类型调用析构函数的区别
解读:可以看到我们在实例化阶段初始化的日期类 d1
在结束时编译器生成的析构函数对没有对其进行处理,但是对于Mystack
类型的 q1
在结束时,编译器调用了其成员自己的析构函数,进行了空间的释放。虽然日期类 d1
的析构函数没有对其进行处理,但其在结束时函数栈帧已经销毁,不处理其实也没事,但是像 q1
存在动态空间的申请,必须要进行处理的。
4. 析构函数的调用顺序
解读:可以看到在对象的生命周期结束之后,是后定义的st2
先进行的析构。
5. 小结:
如果类里面没有申请资源,一般都不需要写析构函数,但是如果类里面涉及到了资源的申请,除了像Mystack
这种自定义类型,一般都是需要自己来写析构函数的。
四:拷贝构造函数
如果一个构造函数的第一个参数是自身类类型的引用,且任何额外的参数都有默认值,则此构造函数也叫做拷贝构造函数,也就是拷贝构造是一个特殊的构造函数。
拷贝构造函数的特点:
- 拷贝构造函数是构造函数的一个重载。
- 拷贝构造函数的第一个参数必须是类类型对象的引用,使用传值方式编译器直接报错,因为语法逻辑上会引发无穷递归调用。拷贝构造函数也可以多个参数,但是第一个参数必须是类类型对象的引用,后面的参数必须有缺省值。
- C++规定自定义类型对象进行拷贝行为必须调用拷贝构造,所以这里自定义类型传值传参和传值返回都会调用拷贝构造完成。
- 若未显式定义拷贝构造,编译器会自动生成拷贝构造函数。自动生成的拷贝构造对内置类型成员变量会完成值拷贝/浅拷贝(一个字节一个字节的拷贝),对自定义类型成员变量会调用他的拷贝构造。
- 像
Date
这样的类成员变量全是内置类型且没有指向什么资源,编译器自动生成的拷贝构造就可以完成需要的拷贝,所以不需要我们显示实现拷贝构造。像Stack
这样的类,虽然也都是内置类型,但是_a
指向了资源,编译器自动生成的拷贝构造完成的值拷贝/浅拷贝不符合我们的需求,所以需要我们自己实现深拷贝(对指向的资源也进行拷贝)。像MyQueue
这样的类型内部主要是自定义类型Stack
成员,编译器自动生成的拷贝构造会调用Stack
的拷贝构造,也不需要我们显示实现MyQueue
的拷贝构造。这里还有一个小技巧:如果一个类显示实现了析构并释放资源,那么他就需要显示写拷贝构造,否则就不需要。 - 传值返回会产生一个临时对象调用拷贝构造,传值引用返回,返回的是返回对象的别名(引用),没有产生拷贝。但是如果返回对象是一个当前函数局部域的局部对象,函数结束就销毁了,那么使用引用返回是有问题的,这时的引用相当于一个野引用,类似一个野指针一样。传引用返回可以减少拷贝,但是一定要确保返回对象,在当前函数结束后还在,才能用引用返回。
1. 拷贝构造函数形式
解读:这里是利用拷贝构造来对另一个对象进行初始化,这里其实是会将d2
的地址传过去,然后在拷贝构造函数中通过this
指针来对d2
进行初始化。
注意:如果拷贝构造函数这里的参数不加const
的话,很可能会出现一系列的错误
下面给这样一个场景
这里我们没有加const
,因此就算出现了权限放大的情况,这里也没有进行报错,所以建议加上const
比较好。
2. 拷贝构造函数无限递归问题分析
首先来看一个较为简单的例子:
再来看一个复杂的情况:
解读:由于拷贝构造函数是传值传参,因此在每次调用拷贝构造之前都会进行传值传参,但是每次传值传参都会生成新的拷贝构造,这样就形成了无穷递归。
打个比方:其实就像一件事需要你亲自去做,但是你交给了手下的一个人,手下的这个人又交给下一个人,就这样一直重复下去,最终这件事怎么也做不成。
3. 深拷贝/浅拷贝引发的问题
错因分析:
这里我们在对栈进行拷贝构造的时候出现了问题,因为浅拷贝不适合于栈,因为栈里面存在动态申请的资源_a
,因此浅拷贝的话会造成s1
和s2
指向了同一块空间,但是在对象的生命周期结束之后,析构函数是会调用两次,也就是说同一块空间会释放两次,这样不就出错了嘛。因此这里需要深拷贝来解决。
这里在进行拷贝构造时,先为_a
申请一块空间,之后再利用memcpy
进行拷贝,
这样就不会产生问题了。
4. 小结:
如果一个类显示实现了析构并释放资源,那么他就需要显示写拷贝构造(深拷贝),否则就不需要。
五:运算符重载
- 当运算符被用于类类型的对象时,C++语言允许我们通过运算符重载的形式指定新的含义。C++规定类类型对象使用运算符时,必须转换成调用对应运算符重载,若没有对应的运算符重载,则会编译报错。
- 运算符重载是具有特殊名字的函数,他的名字是由
operator
和后面要定义的运算符共同构成。和其他函数一样,它也具有其返回类型和参数列表以及函数体。 - 重载运算符函数的参数个数和该运算符作用的运算对象数量一样多。一元运算符有一个参数,二元运算符有两个参数,二元运算符的左侧运算对象传给第一个参数,右侧运算对象传给第二个参数。
- 如果一个重载运算符函数是成员函数,则它的第一个运算对象默认传给隐式的
this
指针,因此运算符重载作为成员函数时,参数比运算对象少一个。 - 运算符重载以后,其优先级和结合性与对应的内置类型运算符保持一致。
- 不能通过连接语法中没有的符号来创建新的操作符:比如
.* :: sizeof ?: .
注意以上5
个运算符不能重载。(选择题里面常考,大家要记⼀下) - 重载操作符至少有一个类类型参数,不能通过运算符重载改变内置类型对象的含义,如:
intoperator+(int x, int y)
- 一个类需要重载哪些运算符,是看哪些运算符重载后有意义,比如
Date
类重载operator-
就有意义。 - 重载
++
运算符时,有前置++
和后置++
,运算符重载函数名都是operator++
,⽆法很好的区分。C++规定,后置++
重载时,增加一个int
形参,跟前置++
构成函数重载,方便区分。 - 重载
<<
和>>
时,需要重载为全局函数,因为重载为成员函数,this
指针默认抢占了第一个形参位置,第一个形参位置是左侧运算对象,调用时就变成了对象<<cout
,不符合使用习惯和可读性。重载为全局函数把ostream/istream
放到第⼀个形参位置就可以了,第二个形参位置当类类型对象。
场景一:不包含类类型形参的重载
场景二:对[]
运算符重载
这里用到了之前实现过的顺序表
解读:这里我们通过对[]
的重载,让seqlist
类也能像数组一样对数组元素进行操作,这里我们采取了引用返回,可以减少拷贝,提高效率,并且还可以对数组元素进行修改。
可以看到我们还可以对数组元素进行修改。
场景三:对 ==
运算符的重载
一开始我们会这样写:
但是由于这些变量是类里面的私有成员,无法在外类外访问,但是我们要实现==
的重载需要访问这些成员,那么该怎么办呢?
方法一:将私有成员放开
但是这样写有点不合适,因为不用const
限制的话,很有可能会出现权限放大的情况,因此还是加上const
比较好
方法二:通过公共函数来获取私有成员
这里为什么后面要加const
还无法解释,后面再讲解
方法三:将重载定义在类里面
我们刚开始可能会这样写:
但这里为什么报错参数过多呢?从前面对重载的介绍我们得知,运算符的重载的参数要和其运算对象的数量一样多,这里的==
的作用对象是两个,因此这里重载的参数也应该是两个,但是这里我们不是写了两个参数吗?别忘了在类里面的函数参数第一个都默认为this
指针,因此这里一共有三个参数,因此才会报错,因此只需保留一个即可,第一个类的地址会被this
指针接收的。
左边其实就是this
指针代表了d1
来和d2
作比较。
其实这里的重载写成显示的也可以:
场景四:对 =
赋值运算符重载
赋值运算符重载是一个默认成员函数,用于完成两个已经存在的对象直接的拷贝赋值,这里要注意跟拷贝构造区分,拷贝构造用于一个对象拷贝初始化给另一个要创建的对象。
赋值运算符重载的特点:
- 赋值运算符重载是⼀个运算符重载,规定必须重载为成员函数。赋值运算重载的参数建议写成
const
当前类类型引用,否则传值传参会有拷贝。 - 有返回值,且建议写成当前类类型引用,引用返回可以提高效率,有返回值目的是为了支持连续赋值场景。
- 没有显式实现时,编译器会自动生成一个默认赋值运算符重载,默认赋值运算符重载行为跟默认拷贝构造函数类似,对内置类型成员变量会完成值拷贝/浅拷贝(一个字节一个字节的拷贝),对自定义类型成员变量会调用他的赋值重载函数。
- 像
Date
这样的类成员变量全是内置类型且没有指向什么资源,编译器自动生成的赋值运算符重载就可以完成需要的拷贝,所以不需要我们显示实现赋值运算符重载。像Stack
这样的类,虽然也都是内置类型,但是_a
指向了资源,编译器自动生成的赋值运算符重载完成的值拷贝/浅拷贝不符合我们的需求,所以需要我们自己实现深拷贝(对指向的资源也进行拷贝)。像MyQueue
这样的类型内部主要是自定义类型Stack
成员,编译器自动生成的赋值运算符重载会调用Stack
的赋值运算符重载,也不需要我们显示实现MyQueue
的赋值运算符重载。这里还有⼀个小技巧,如果一个类显示实现了析构并释放资源,那么他就需要显示写赋值运算符重载,否则就不需要。
初始情况我们可能写成这样:
注:有返回值是为了支持连续赋值的情况
但是这里会存在一个问题:当一个对象自己给自己赋值时是不是就没有必要再执行赋值的逻辑了呢?因此这里加上一个判断比较好。
我们知道传值返回会调用拷贝构造,因此这里用传引用返回的话可以减少拷贝,提高效率,并且this
指针也不会消失,因此这里狠狠用引用返回。
赋值操作没问题。
连续赋值也没问题。
场景五: 赋值运算符与拷贝构造的区分
记住这句话:赋值运算符重载是针对两个已经存在的对象,而拷贝构造是在实例化对象的时候进行的。
约定:
下面我们就在完善日期类的基础上实现其他的运算符重载。
场景六:+=
运算符重载(日期和天数)
由于这里的日期类加天数有可能会牵扯到月份以及年份的进位,但是每个月份的天数不是全部相同,因此这里我们要先实现获取每个月天数的函数。
为了方便获取每个月份的天数,这里我们创建了一个月份数组,为避免频繁创建,这里我们将其定义成了静态数组,后面只需特判一下二月的不同情况即可。
(这里的if
判断条件中的小细节就是将判断是否是二月条件放在前面,能快速筛选不满足条件的情况)
重载+=
运算符实现:
注:这里为了避免拷贝,这里我们采取传引用返回。
通过测试可以发现实现的+=
运算符没有问题。
场景七:+
运算符重载(日期和天数)
这里我们就可以通过复用上面实现的+=
运算符来实现+
运算符的重载。
通过测试可以看到,d2
确实是d1
的100天之后,而且d1
也没有改变,没有问题。
场景八:+
运算符重载和+=
运算符重载的复用分析
前面我们通过复用+=
运算符重载来实现的+
运算符的重载,其实我们也可以先将+
运算符的重载实现好,然后复用+
运算符的重载来实现+=
运算符的重载。
其实现逻辑与+=
运算符重载的逻辑基本上一模一样,只是需要一个临时对象来代替其来进行运算。
注:这里需要注意的是这里因为返回的是一个临时变量,因此不能用引用返回。
复用+
运算符重载来实现+=
运算符重载:
分析这两种实现方式的优劣:
场景九:-=
运算符重载(日期和天数)
这里的-=
是针对某个日期加上一个天数来重载的,逻辑实现和+=
类似,先让天数减去这个天数,只要小于0就一直向月份借位。
场景十:-
运算符重载(日期和天数)
这里-
的重载就可以复用上面-=
运算符的重载。
场景十一: + += - -=
运算符重载的遗留问题
上面我们实现了这些运算符的重载,但是实现的还是不够严谨,比如这里的+=
可能会加上一个负值,这时候的_day
可能就是一个负值,连while
循环都进不去,这里的-=
也可能会减去一个负值,这时候的_day
就是一个正数,连while
循环都进不去,因此这里都需要特判一下:
场景十二:前置++
和后置++
运算符重载
首先先来看C++的一个规定:
前置++
重载时不带参数,后置++
要带参,相当于强制构成函数重载了。
由于后置++
返回的是一个临时变量,因此不能用引用。
可以看到测试没问题。
场景十三:前置--
和后置--
运算符重载
场景十四:-
运算符重载(日期和日期)
对于两个日期的相减,由于月份的不统一,还要处理借位的情况,很麻烦,但是我们其实可以换一种思路,如果我们先确定两个日期的大小,让较小的那个日期一直加1,用一个计数器来记录两者相差多少天,一直到两者相等就停止,这样就可以知道两个日期的天数差了。
场景十五:比较运算符的重载
在实现完<
运算符的重载之后就可以复用这个来实现其他比较运算符的重载。
六:const成员函数
我们先来看下面这个场景:
这里我们用const
来修饰实例化出的对象d1
时,会发现d1
不能调用Print
函数了,那么这是为什么呢?其实这里牵扯到了权限的放大。
但是由于this指针是隐式传参的,这里我们该怎么样来加const呢?
其实C++给出了解决方法:
只需在成员函数列表的后面加上const即可。
这样this指针就由Date* const this
变为 const Date* const this
这样不管是const修饰的对象还是没有const修饰的对象都可以调用成员函数了。
小结:
- 将
const
修饰的成员函数称之为const
成员函数,const
修饰成员函数放到成员函数参数列表的后面。 const
实际修饰该成员函数隐含的this
指针,表明在该成员函数中不能对类的任何成员进行修改。const
修饰Date
类的Print
成员函数,Print
隐含的this
指针由Date* const this
变为const Date* const this
七:取地址运算符重载
- 取地址运算符重载分为普通取地址运算符重载和
const
取地址运算符重载,一般这两个函数编译器自动生成的就可以够我们用了,不需要去显示实现。 - 除非一些很特殊的场景,比如我们不想让别人取到当前类对象的地址时就可以重载取地址运算符,胡乱返回一个地址。
编译器自动生成的取地址运算符逻辑一般都是这样:
重载取地址运算符
这时候就是一个假地址。
但是这样写其实没有什么实际意义。
八:完结:
撒花!!!
相关文章:
《类和对象(中)》
引言: 上次我们主要学习了类的相关知识,今天我们就来学习类和对象(中),今天也会用到之前学习过的东西,可以说是前面知识的结合,较前面会难一点(打个预防针)。 一:类的默认成员函数…...
SSH终端登录与网络共享
SSH 是较可靠,专为远程登录会话和其他网络服务提供安全性的协议 注意 SSH终端登录的前提是:电脑和板卡都能够通过网络相连接及通信 与连接互联网不一样,SSH可以不用互联网,只要电脑和板卡组成一个小型网络即可 网络方案 如果您…...
n8n系列(5):LangChain与大语言模型应用
引言 n8n作为一个强大的工作流自动化平台,可以通过集成LangChain框架,为用户提供了便捷地利用OpenAI、Azure OpenAI等大语言模型的能力。 本文将深入探讨n8n中的AI集成功能,特别是LangChain节点的使用,以及如何构建智能化的工作流程来解决实际业务问题。 1. n8n的AI集成概…...
springboot3+vue3融合项目实战-大事件文章管理系统-更新用户信息
在一下三个代码处进行修改 在UserController里面增加uadate方法 PutMapping ("/update")public Result update(RequestBody Validated User user){userService.update(user);return Result.success();}在userservice中增加update方法 void update(User user); 然…...
20250510-查看 Anaconda 配置的镜像源
打开 Anaconda Prompt 查看 Anaconda 当前配置的镜像源,使用命令 conda config --show channels这将显示当前配置的通道(channels),即镜像源列表。 此外,还可以使用 conda config --show命令来显示conda的配置信息&…...
CDGP数据治理主观题评分标准与得分策略
1.数据模型题目评分标准 1)准确理解题目中所描述的业务逻辑和需求得[1分] 2)正确使用模型设计方法,使用信息工程、信息建模集成定义、巴克符号、陈氏符号等其中一种得[1分] 3)正确设计实体和属性,题目中涉及的实体数量为25-30个,10个以内得[2分],10-20个得[3分],25个…...
[学习]RTKLib详解:sbas.c与rtcm.c
RTKLib详解:sbas.c与rtcm.c 本文是 RTKLlib详解 系列文章的一篇,目前该系列文章还在持续总结写作中,以发表的如下,有兴趣的可以翻阅。 [学习] RTKlib详解:功能、工具与源码结构解析 [学习]RTKLib详解:pntp…...
【基础IO下】磁盘/软硬链接/动静态库
前言: 文件分为内存文件和磁盘文件。磁盘文件是一个特殊的存在,因为磁盘文件不属于冯诺依曼体系,而是位于专门的存储设备中。因此,磁盘文件存在的意义是将文件更好的存储起来,一边后续对文件进行访问。在高效存储磁盘…...
JAVA练习题(1) 卖飞机票
import java.util.Scanner; public class Main {public static void main(String[] args) {Scanner scnew Scanner(System.in);System.out.println("请输入飞机的票价:");int pricesc.nextInt();System.out.println("请输入月份:");…...
SpringBoot框架开发网络安全科普系统开发实现
概述 基于SpringBoot框架的网络安全科普系统开发指南,该系统集知识科普、案例学习、在线测试等功能于一体,本文将详细介绍系统架构设计、功能实现及技术要点,帮助开发者快速构建专业的网络安全教育平台。 主要内容 系统功能架构 本系统采…...
机器学习 day02
文章目录 前言一、TF-IDF特征词重要度特征提取二、无量纲化处理1.最大最小值归一化2.normalize归一化3.StanderScaler标准化 前言 通过今天的学习,我掌握了TF-IDF特征词重要度特征提取以及无量纲化处理的相关知识和用法 一、TF-IDF特征词重要度特征提取 机器学习算…...
《AI大模型应知应会100篇》第53篇:Hugging Face生态系统入门
第53篇:Hugging Face生态系统入门 ——从模型获取到部署的全流程实战指南 📌 摘要 在人工智能快速发展的今天,Hugging Face已成为自然语言处理(NLP)领域最具影响力的开源平台之一。它不仅提供丰富的预训练模型、强大…...
计网学习笔记———网络
🌿网络是泛化的概念 网络是泛化的概念 🍂泛化理解 网络的概念在生活中无处不在举例:社交网络、电话网路、电网、计算机网络 🌿网络的定义 定义: 离散的个体通过通讯手段连成群体,实现资源的共享与交流、个…...
Vue3 怎么在ElMessage消息提示组件中添加自定义icon图标
1、定义icon组件代码: <template><svg :class"svgClass" aria-hidden"true"><use :xlink:href"iconName" :fill"color"/></svg> </template><script> export default defineComponen…...
17.Excel:实用的 VBA 自动化程序
一 excel 设置 开始-选项 二 批量创建工作表 某工作簿用于保存31天的东西,手动创建31个工作表不方便。 A1单元格输入内容,或者空着。从A2单元格开始,一定要以字符形式的,不能以数值和日期形式。12345这是数值形式,1月…...
Kubernetes生产实战(十六):集群安全加固全攻略
Kubernetes集群安全加固全攻略:生产环境必备的12个关键策略 在容器化时代,Kubernetes已成为企业应用部署的核心基础设施。但根据CNCF 2023年云原生安全报告显示,75%的安全事件源于K8s配置错误。本文将基于生产环境实践,系统讲解集…...
Cadence学习笔记之---导入PCB板框、网表
目录 01 | 引 言 02 | 环境描述 03 | 导入PCB板框 04 | 自画PCB板框 05 | 导入PCB网表 06 | 总 结 01 | 引 言 在上一篇小记中讲述了创建PCB工程的操作步骤、PCB工程中的类与子类,以及Cadence颇具特色的颜色管理器。 本篇小记主要记述如何导入PCB板框、自画…...
嵌入式硬件篇---麦克纳姆轮(简单运动实现)
文章目录 前言1. 麦克纳姆轮的基本布局X型布局O型布局 2. 运动模式实现原理(1) 前进/后退前进后退 (2) 左右平移向左平移向右平移 (3) 原地旋转顺时针旋转(右旋)逆时针旋转(左旋) (4) 斜向移动左上45移动 (5) 180旋转 3. 数学原理…...
en33网络配置文件未托管
从 nmcli device status 的输出可以看到,所有网络设备(包括 ens33)都处于 "未托管"(unmanaged)状态,这导致 NetworkManager 和传统的 network.service 都无法管理网络接口,从而引发 n…...
嵌入式学习--江协51单片机day4
昨天周五没有学习,因为中午没有睡觉,下午和晚上挤不出整块的时间。周日有考试今天也没有学很多啊,但以后周末会是学一天,另一天休息和写周总结。 今天学了串口通信和LED点阵屏,硬件原理是真的很迷,一但想搞…...
Hadoop 2.x设计理念解析
目录 一、背景 二、整体架构 三、组件详解 3.1 yarn 3.2 hdfs 四、计算流程 4.1 上传资源到 HDFS 4.2 向 RM 提交作业请求 4.3 RM 调度资源启动 AM 4.4 AM运行用户代码 4.5 NodeManager运行用户代码 4.6 资源释放 五、设计不足 一、背景 有人可能会好奇…...
diy装机成功录
三天前,我正式开启了这次装机之旅,购入了一颗性能强劲的 i5-12400 CPU,一块绘图能力出色的 3060ti 显卡,还有技嘉主板、高效散热器、16G 内存条、2T 固态硬盘,以及气派的机箱和风扇,满心期待能亲手打造一台…...
睿思量化小程序
睿思量化小程序是成都睿思商智科技有限公司最新研发和运营的金融数据统计分析工具,旨在通过量化指标筛选与多策略历史回测,帮助用户科学配置基金资产,成为个人投资者与机构用户的“智能化财富管家”。 核心功能:数据驱动决策&…...
STM32实现九轴IMU的卡尔曼滤波
在嵌入式系统中,精确的姿态估计对于无人机、机器人和虚拟现实等应用至关重要。九轴惯性测量单元(IMU)通过三轴加速度计、陀螺仪和磁力计提供全面的运动数据。然而,这些传感器数据常伴随噪声和漂移,单独使用无法满足高精…...
JS DOM操作与事件处理从入门到实践
对于前端开发者来说,让静态的 HTML 页面变得生动、可交互是核心技能之一。实现这一切的关键在于理解和运用文档对象模型 (DOM) 以及 JavaScript 的事件处理机制。本文将带你深入浅出地探索 DOM 操作的奥秘,并掌握JavaScript 事件处理的方方面面。 目录 …...
Hive表JOIN性能问
在处理100TB的Hive表JOIN性能问题时,需采用分层优化策略,结合数据分布特征、存储格式和计算引擎特性。以下是系统性优化方案: 1. 数据倾斜优化(Skew Join) 1.1 识别倾斜键 方法:统计JOIN键的分布频率&…...
关键点检测--使用YOLOv8对Leeds Sports Pose(LSP)关键点检测
目录 1. Leeds Sports Pose数据集下载2. 数据集处理2.1 获取标签2.2 将图像文件和标签文件处理成YOLO能使用的格式 3. 用YOLOv8进行训练3.1 训练3.2 预测 1. Leeds Sports Pose数据集下载 从kaggle官网下载这个数据集,地址为link,下载好的数据集文件如下…...
2025年客运从业资格证备考单选练习题
客运从业资格证备考单选练习题 1、从事道路旅客运输活动时,应当采取必要措施保证旅客的人身和财产安全,发生紧急情况时,首先应( )。 A. 抢救财产 B. 抢救伤员 C. 向公司汇报 答案:B 解析:…...
QMK自定义4*4键盘固件创建教程:最新架构详解
QMK自定义4*4键盘固件创建教程:最新架构详解 前言 通过本教程,你将学习如何在QMK框架下创建自己的键盘固件。QMK是一个强大的开源键盘固件框架,广泛用于DIY机械键盘的制作。本文将详细介绍最新架构下所需创建的文件及其功能。 准备工作 在…...
获取conan离线安装包
1、获取conan离线安装包 # apt-get install python3.12-venv pip #缓存的安装存放在/var/cache/apt/archives目录 # mkdir /myenv && cd /myenv #创建虚拟环境目录 # python3 -m venv myenv #创建虚拟环境 # source myenv/bin/activate #激活虚拟环境ÿ…...
【Java ee初阶】网络原理
应用层 由于下面的四层都是系统已经实现好了的,但是应用层是程序员自己写的,因此应用层是程序员最重要的一层。 应用层中,程序员通常需要定义好数据传输格式,调用传输层api(socket api)进行真正的网络通信…...
Makefile中 链接库,同一个库的静态库与动态库都链接了,生效的是哪个库
Makefile中 链接库,同一个库的静态库与动态库都链接了,生效的是哪个库 在 Makefile 中同时链接同一个库的静态库(.a)和动态库(.so)时,具体哪个库生效取决于链接顺序和编译器行为。以下是详细分析…...
【AI提示词】金字塔模型应用专家
提示说明 专业运用金字塔原理优化信息结构与逻辑表达,实现高效精准的思维传达。 提示词 # Role: 金字塔模型应用专家 ## Profile - **language**: 中文/英文 - **description**: 专业运用金字塔原理优化信息结构与逻辑表达,实现高效精准的思维传…...
电子电器架构 --- 车载以太网拓扑
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…...
使用FastAPI微服务在AWS EKS上实现AI会话历史的管理
架构概述 本文介绍如何使用FastAPI构建微服务架构,在AWS EKS上部署两个微服务: 服务A:接收用户提示服务B:处理对话逻辑,与Redis缓存和MongoDB数据库交互 该架构利用AWS ElastiCache(Redis)实现快速响应,…...
Flutter PIP 插件 ---- 为iOS 重构PipController, Demo界面,更好的体验
接上文 Flutter PIP 插件 ---- 新增PipActivity,Android 11以下支持自动进入PIP Mode 项目地址 PIP, pub.dev也已经同步发布 pip 0.0.3,你的加星和点赞,将是我继续改进最大的动力 在之前的界面设计中,还原动画等体验一…...
vue开发用户注册功能
文章目录 一、开发步骤二、效果图三、搭建页面创建views/Login.vue在App.vue中导入Login.vue 四、数据绑定五、表单校验六、访问后端 API 接口,完成注册七、完整的Login.vue代码八、参考资料 一、开发步骤 二、效果图 三、搭建页面 创建views/Login.vue 完整内容在…...
Qt中的RCC
Qt资源系统(Qt resource system)是一种独立于平台的机制,用于在应用程序中传输资源文件。如果你的应用程序始终需要一组特定的文件(例如图标、翻译文件和图片),并且你不想使用特定于系统的方式来打包和定位这些资源,则可以使用Qt资源系统。 最…...
muduo源码解析
1.对类进行禁止拷贝 class noncopyable {public:noncopyable(const noncopyable&) delete;void operator(const noncopyable&) delete;protected:noncopyable() default;~noncopyable() default; }; 2.日志 使用枚举定义日志等级 enum LogLevel{TRACE,DEBUG,IN…...
Qt QCheckBox 使用
1.开发背景 Qt QCheckBox 是勾选组件,具体使用方法可以参考 Qt 官方文档,这里只是记录使用过程中常用的方法示例和遇到的一些问题。 2.开发需求 QCheckBox 使用和踩坑 3.开发环境 Window10 Qt5.12.2 QtCreator4.8.2 4.功能简介 4.1 简单接口 QChec…...
【工具记录分享】提取bilibili视频字幕
F12大法 教程很多 但方法比较统一 例快速提取视频字幕!适用B站、AI字幕等等。好用 - 哔哩哔哩 无脑小工具 哔哩哔哩B站字幕下载_在线字幕解析-飞鱼视频下载助手 把链接扔进去就会自动生成srt文件 需要txt可以配合: SRT转为TXT...
设计模式【cpp实现版本】
文章目录 设计模式1.单例模式代码设计1.饿汉式单例模式2.懒汉式单例模式 2.简单工厂和工厂方法1.简单工厂2.工厂方法 3.抽象工厂模式4.代理模式5.装饰器模式6.适配器模式7.观察者模式 设计模式 1.单例模式代码设计 为什么需要单例模式,在我们的项目设计中&…...
Python数据分析案例74——基于内容的深度学习推荐系统(电影推荐)
背景 之前都是标准的表格建模和时间序列的预测,现在做一点不一样的数据结构的模型方法。 推荐系统一直是想学想做的,以前读研时候想学没多少相关代码,现在AI资源多了,虽然上班没用到这方面的知识,但是还是想熟悉一下…...
C PRIMER PLUS——第8节:字符串和字符串函数
目录 1. 字符串的定义与表示 2. 获取字符串的两种方式 3.字符串数组 4. 字符串输入函数 4.1 gets()(不推荐使用,有缓冲区溢出风险) 4.2 fgets()(推荐使用) 4.3 scanf() 4.4 gets_s()(C11 标准&…...
Dia浏览器:AI驱动浏览网页,究竟怎么样?(含注册申请体验流程)
名人说:博观而约取,厚积而薄发。——苏轼《稼说送张琥》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、Dia浏览器简介1. 什么是Dia浏览器2. 开发背景与公司简介3. 与传统浏览器的区别 …...
milvus+flask山寨复刻《从零构建向量数据库》第7章
常规练手,图片搜索山寨版。拜读罗云大佬著作,结果只有操作层的东西可以上上手。 书中是自己写的向量数据库,这边直接用python拼个现成的milvus向量数据库。 1. 创建一个向量数据库以及对应的相应数据表: # Milvus Setup Argume…...
【大数据技术-HBase-关于Hmaster、RegionServer、Region等组件功能和读写流程总结】
Hmaster的作用 负责命名空间、表的创建和删除等一些DDL操作、region分配和负载均衡,并不参与数据读写,相比与其他大数据组件,如hdfs的namenode,在hbase中,Hmaster的作用是比较弱化的,即使挂掉,也暂时不影响现有表的读写。 RegionServer的作用 一个机器上一个regionse…...
用c语言实现——一个交互式的中序线索二叉树系统,支持用户动态构建、线索化、遍历和查询功能
知识补充:什么是中序线索化 中序遍历是什么 一、代码解释 1.结构体定义 Node 结构体: 成员说明: int data:存储节点的数据值。 struct Node* lchild:该节点的左孩子 struct Node* rchild:该节点的右孩子…...
Pale Moon:速度优化的Firefox定制浏览器
Pale Moon是一款基于Firefox浏览器的定制版浏览器,专为追求速度和性能的用户设计。它使用开放源代码创建,经过高度优化,适用于现代处理器,提供了更快的页面加载速度和更高效的脚本处理能力。Pale Moon不仅继承了Firefox的安全性和…...
广东省省考备考(第七天5.10)—言语:逻辑填空(每日一练)
错题 解析 第一空,搭配“各个环节”,根据“我国已经形成了相对完善的中药质量标准控制体系”可知,横线处应体现“包含”之意,C项“涵盖”指包括、覆盖,D项“囊括”指把全部包罗在内,均与“各个环节”搭配得…...