C++——C++11(1)

时至今日,C++标准已经到了C++23,但是你要说哪一次提出的标准最经
典,那C++11一定会被人提及,C++11带来了数量可观的变化,其中包
含了约140个新特性,以及对C++03标准中约600个缺陷的修正,这使得
C++11更像是从C++98/03中孕育出的一种新语言。所以对于学习C++的人
来说,认识C++11中部分的新特性是必要的。而今天由我来浅显的介绍其
中的部分特性。

1. 列表初始化

在C语言中我们对结构体和数组的初始化会像下面这么写:
在这里插入图片描述
而在C++中我们初始化一个对象的时候也会使用上面结构体那样的方式来初始化对象,但是在C++中我们更趋向使用STL容器来存储对象,而不是简单的一个数组了,而C语言中这种初始化数组的方法有很好,所以C++11中采用了这种方法,并且对花括号的初始化进行了天翻地覆的改造,你会看到下面这样的情况:
在这里插入图片描述

使得一切对象都可以使用花括号初始化,向上面这种对单体对象的初始化则只是根据构造函数对应的参数个数决定比如变量k、j、paa中的元素,它们的参数都是固定的,我们进行更改的话编译器会报错。但是下面这种情况呢?
在这里插入图片描述
我们上面说了对一个单体对象的初始化受它的构造函数影响,这里怎么不会呢?难道vector和list都写了三个参数和六个参数的构造函数吗?显然不是的。而这就是列表初始化。
对于部分容器的初始化来说,等号右边的话括号里的内容会变成一个这样的对象:
在这里插入图片描述
它的底层也很简单,只不过是两个指针来只想这一串内容。它的成员函数也很简单:
在这里插入图片描述
而像vector、list这些容器里也都写好了关于initializer_list对象的构造函数:
在这里插入图片描述
在这里插入图片描述
才能支持上面那样vector和list的初始化。而假如像我们自己尝试写一个list的时候也可以写这样的一个构造函数来帮我们实现这样的功能:
在这里插入图片描述
可以看到我们这样直接写是不行的,在我们自己实现的list中写一个关于initializer_list对象的构造就可以了:
在这里插入图片描述
这样就可以了:
在这里插入图片描述
需要在这里注意的是:

1.多参数对象的花括号构造实际上是先将花括号的内容构造出一个临时对象,然后再拷贝
构造给等式左面的对象,但是编译器直接优化成直接构造了。
2.vector的列表初始化跟多参数对象初始化的隐式类型转换还是不一样的

2.右值引用

a. 左值与右值

我们来再次认识一下什么是左值,什么是右值。单从字面意思来说,右值左值就是等号右面和等号左面的值,但是肯定不会这么简单,就像位操作中的左右移一样,左移就是往左移,右移就是往右移吗?也不一定,在计算机中左右移是看计算机的存储方式的,而左右值也一样,不能单纯的用左右来区分左值右值。常见的左值我们一般很容易分辨,下面我来介绍一些常见的右值:

在这里插入图片描述
还是无法判别的时候,可以取地址的就是左值,不可以的就是右值

2. 什么是右值引用?

我们倒是学过一个引用,但哪个是左值引用,左值引用可不可以直接引用右值呢?答案是不可以,因为右值是具有常性的值,而我们要使用一个正常的引用变量给它起别名等于是权限的放大。
而可以这样来书写:
在这里插入图片描述
那么在C++11就出现了对右值的引用:
在这里插入图片描述
左值引用不能直接给右值起别名,那么右值引用可以直接给左值起别名吗?那当然也是不可以的,但是可以是用其他方式来实现:
在这里插入图片描述
其中的move把变量i的“属性”(这个属性不详细述说)发生了改变,导致i成为了右值。但是需要注意:

其中被move执行的变量只会在当前行被修改属性,其他行是不会改变的

c. 右值引用的意义

一个东西被提出来肯定是有他的道理,那具体右值引用有什么意义,继续往下看。
在C++中有了左值引用后,我们实现了函数传参传引用,函数返回引用(赋值重载等等),但是其中的函数返回左值引用,那是需要被返回的对象出了函数作用域之后依然存在。要不然就会造成内存的越界访问。那么在这种情况下,就会导致很尴尬的情况发生:
在这里插入图片描述
让我来阐述一下上面的代码,类A中有一个int的指针,我将它设置成指向固定十个int的数组,而上面的函数我只是将一个int的每一位给拆分到这个数组中的一个函数。(只是为了能够说明要讲述的东西,所以举的例子的实现不会很严谨)
当我们运行之后:
在这里插入图片描述
在这里要注意:

我使用的是VS2019,VS2022会将这里直接优化成构造,但是这里的问题是确实存在的。

当我运行代码之后,发现它进行了一次拷贝构造和赋值,而这其中函数中的aa是一个存在于func中的局部变量,我们进行的是值返回所以在return的时候会使用拷贝构造构造出一个临时对象,然后再是用这个临时对象赋值给main函数里的变量a。
又要注意了:

这里有人可能会问,这里不也是被大多数编译器优化成直接构造吗?这个认识显然是混淆了。
正确的认识是:大多数编译器会将拷贝构造+构造直接优化成拷贝构造。这里是拷贝构造+赋值,所以不会有优
化的现象,新一点的编译器才会。

在这里插入图片描述
这样才会优化。
回归正题,那么我们发现,他进行了两次深拷贝,这种现象从比较严谨的角度来说是比较浪费的,因为我们需要的就是func函数中的aa变量中开辟空间中的那部分内容,但是我们硬生生又开辟了两个同样大小的空间才能达到让a获得aa的内容,这么看来光是空间就浪费了三倍。所以有没有一种办法解决这种现象让aa中的内容直接给了a呢?这种情况下,左值引用就无法解决,因为aa在函数中,在函数结束时,它的销毁是必然的。所以就出现了右值引用。
那么,如何使用右值引用解决这个问题呢?
返回右值引用吗?这种是行不通的,因为我们已经说了,aa的销毁是必然的。
全局变量?更不行了,全局变量的使用是有风险的,不能随意使用全局变量。
这里就提出了移动构造和移动赋值的方法:

移动赋值重载

我们知道上面两次深拷贝的实现大致是如下图:
在这里插入图片描述
其中,临时变量具有常性它是一个右值,而且它被使用完就销毁了,那能不能将它的内容给了我们的a呢?我们来看看A类的赋值重载:
在这里插入图片描述
发现他是一个左值引用,但是加了一个const之后使得他也能实现右值的赋值重载,在C++泛型编程的思想中,秉持着有现成的用现成的,没有现成的用将就的。所以这里的临时变量就传给了左值引用的赋值重载函数,那我们写一个右值引用的会怎么样呢?
我们的写法如下:
在这里插入图片描述
再次执行代码:
在这里插入图片描述
可以看到我们,的移动赋值,并没有深拷贝,而是只交换了两者的指针,大大提高了效率。

移动拷贝构造

那在拷贝构造的过程中,aa中的资源我们可不可以拿过来呢?为了提升效率,我们一般把即将被销毁的的自定义类型定义为“将亡值”,内置类型定义为纯右值。

将亡值(rvalue reference)通常是指一个即将被销毁(死亡)的临时对象,它可以通过移动语义来提高程序性能。
将亡值可以用 && 符号表示。
纯右值(prvalue,pure rvalue)是指没有任何名称、生存期或地址的表达式,例如常量、字面量或返回右值的函
数调用。一般来说,纯右值可以作为将亡值出现。将亡值和纯右值在 C++ 中都可以被称为右值(rvalue),但它
们之间存在区别。
将亡值是一个具有名称和可用类型的右值引用,而纯右值没有这些特性。这种分类可以让程序员更好地控制和优化
程序的性能。

所以,被return时候的aa就是一个将亡值,那就是右值。
实现移动拷贝构造:
在这里插入图片描述
在这里插入图片描述
这样就通过右值引用来大大提高了效率,当然这里还有一个重要的知识,那就是这两个函数是移动语义的一部分,它们与移动语义紧密相关。
基于这样的情况,我们可以写出这样的代码来提升效率:
在这里插入图片描述
可以看出这种适用于a已经是一个废弃的值。所以使用的时候要谨慎。而STL中也使用了各种右值引用的版本。
在这里插入图片描述
在这里插入图片描述
可以自行去查看。

万能模板和完美转发

出现了右值引用后,就出现了一个新的现象:
在这里插入图片描述
在这里插入图片描述
首先我们看到不可思议的一幕,我们能理解上面的func函数是一个模板函数,并且函数模板参数是右值引用,但是我们看到变量a、b(虽然又有const,但他是常变量),也能能传过去并执行,const也能。其实这里应该是做了特殊处理,当模板和右值引用结合后,他就是一个万能模板了,意思是可以接收任何类型(和属性)的参数。
但是还有一幕,那就是为什么输出结果都是左值引用或者const左值引用啊?
这里就需要注意一点:

关于右值引用传参需要注意,只有当它传过去的时候是作为右值传送,但是当在被传到的函数体中使用这个
参数的时候,他就失去了右值属性而变成一个左值。

所以当我们传送到func函数中调用Fun函数的时候,不管你t是以什么属性过来的,在Fun中就都是左值了。那有没有办法让它一直保持原有的属性呢?那就是完美转发
在这里插入图片描述
看上面的意思:

如果这个值是右值引用类型的话就返回右值引用,如果是左值引用不就返回左值引用。总之就是保留原有属性

那么我们的代码:
在这里插入图片描述
在这里插入图片描述

简单的示例说明

有什么用呢?可以看下面这个例子:
前面我们说了,STL中使用了右值引用的版本,那就意味着构造,赋值重载都使用了。
我们也在自己实现的string和list中简单使用一下右值引用:
先看我写的一部分代码:
首先是string中:
在这里插入图片描述

这其中我写了移动构造和移动赋值。
其次是list:
在这里插入图片描述
list中节点左值和右值不同的构造方式。
在这里插入图片描述
然后是list的各种右值引用版本。
然后我们跑这样一段代码:
在这里插入图片描述
运行结果:
在这里插入图片描述
首先这里string对象s的初始化是构造+拷贝构造优化成直接拷贝构造,这没问题
然后我使用move改变s的属性,变成插入右值,这也没问题。
我的尾插右值封装的是插入右值函数(我认为是),但是他调用的是插入左值函数。
并且,在插入函数中,如果插入数据是右值的话应该调用的是我的右值节点创建,既然是右值节点创建就应该调用string中的移动拷贝构造。而这里调用的是拷贝构造。
综上,有两处是错误的,那么原因是什么呢?上面已经说过了:关于右值引用传参需要注意,只有当它传过去的时候是作为右值传送,但是当在被传到的函数体中使用这个参数的时候,他就失去了右值属性而变成一个左值。
所以我们在这里就应该一直在这条路上维护数据的右值属性,那么有两种方法:

第一种:这条路上的参数使用move移动语义
第二种:这条路上的参数使用完美转发。

我是用第二种,也推荐第二种:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
再次运行:
在这里插入图片描述
这其中第一行的拷贝构造变成了移动拷贝构造,应该是编译器优化的缘故,并不是语法。
注意:

forward是一个模板类,一定要带上模板参数!!!
(我好几次忘带,编译不通过。。)

3.默认成员函数

a. 新增默认成员函数

在之前C++中的默认成员函数只有六个,而之后又添加了两个:
那就是移动构造和移动拷贝,这两个函数的特性和前面六个不太一样:

1.如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载
中的任意一个。那么编译器会自动生成一个默认移动构造。默认生成的移动构造函数,
对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是
否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造。
2.如果你没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值
重载中的任意一个,那么编译器会自动生成一个默认移动赋值。默认生成的移动构造
函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个
成员是否实现移动赋值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。(默
认移动赋值跟上面移动构造完全类似)
3.如果你提供了移动构造或者移动赋值,编译器不会自动提供拷贝构造和拷贝赋值。

上面说的很多,但是我们在实际编写代码的过程中在类中析构、构造、赋值重载都不写的情况太少了,这导致根本不会有默认的移动拷贝和移动赋值生成,所以作为了解即可。

b. default/delete的新意义

强制生成默认函数的关键字default:
  C++11可以让你更好的控制要使用的默认函数。假设你要使用某个默认的函数,但是因为一些原因这个函数没有默认生成。比如:我们提供了拷贝构造,就不会生成移动构造了,那么我们可以使用default关键字显示指定移动构造生成。
禁止生成默认函数的关键字delete:
  如果能想要限制某些默认函数的生成,在C++98中,是该函数设置成private,并且只声明补丁已,这样只要其他人想要调用就会报错。在C++11中更简单,只需在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。

4. 可变参数模板

a. 可变参数模板

在C语言中我们曾对可变参数有着简单的了解:
在这里插入图片描述
在我们以前对模板的认识,他能有类型模板参数和非类型模板参数,但是它的参数的个数是确定的,而在而在C++11中模板和可变参数又产生了新的化学反应:
在这里插入图片描述
看起来是一个很怪的写法。话不多说先来展示它的用法:
在这里插入图片描述
我们看到他能够编译通过,那说明变量args中存储着这四个值,怎么拿到这四个值呢?有两种方法:

通过递归推演来拿到其中的各个值

在这里插入图片描述
关于递归推演还是比较好理解的,实际上编译器会做特殊处理把参数包中的参数一个个给了t,要注意…Args和args…的使用正确使用方式

通过逗号表达式拿到其中的各个参数

在这里插入图片描述
要初始化arr,强行让解析参数包,参数包有一个参数,fun就依次推演生成几个。关于这种用法记住就行。

b. STL容器中的empalce相关接口函数

我们可以看到C++11中出现了一个新的东西:
在这里插入图片描述
它实际用起来跟普通的插入差不多:
在这里插入图片描述
但是我们看到还是有所不同,在使用普通的尾插时,我们是花括号传参,代表传的是一个根据pair构造函数传的一个初始化的列表。但是下面的emplace_back则是直接传了两个参数,这里的原因就是emplace_back使用了可变参数模板:
在这里插入图片描述
我们也来实现一下他这个东西:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
我们看到为什么上面的节点没有拆分args还能初始化呢?当然是pair里就已经有了啊:
在这里插入图片描述

5. Lambda表达式

a. 引入

以前我们要对一个vector(例子)里的内容进行排序我们会这么写:
在这里插入图片描述
但是我们要排的是这样子的元素呢?
在这里插入图片描述
那显然,对于自定义的类,要将他们进行排序,就得有不同的比较规则,那么不同的比较规则又会有许多的仿函数来让我们写,就比如上面我们要分别根据四个成员为依据来一次排序,那我们会这样:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里我只写一个。每个比较依据,都得重写一次仿函数,太费事了,而此时,隔壁的python有一个好东西我们值得借鉴一手,那就是Lambda表达式,但是与python中的不一样,C++中的当然是得跟C++中语言特性有关联:
那我们再次对上面排序做一下修改:
在这里插入图片描述
这就是Lambda表达式。

b. 简单认识

Lambda表达式主要有以下部分组成:

lambda表达式书写格式:[capture-list] (parameters) mutable -> return-type { statement 

}
[capture-list] : 捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用。
(parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略
mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。
->returntype:返回值类型。用追踪返回类型形式声明函数的返回值型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推导。
{statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获
到的变量。
捕捉列表和mutable我们先忽略,那他看起来是不是就和一个函数一样啊:
在这里插入图片描述
只不过写起来有点不一样,那我们现在再来认识一下捕捉列表和mutable是什么?

c. 捕捉列表

捕捉列表描述了上下文中那些数据可以被lambda使用,以及使用的方式传值还是传引用。
[var]:表示值传递方式捕捉变量var
[=]:表示值传递方式捕获所有父作用域中的变量(包括this)
[&var]:表示引用传递捕捉变量var
[&]:表示引用传递捕捉所有父作用域中的变量(包括this)
[this]:表示值传递方式捕捉当前的this指针

注意:

a. 父作用域指包含lambda函数的语句块
b. 语法上捕捉列表可由多个捕捉项组成,并以逗号分割。比如:[=, &a, &b]:以引用传递的方式捕捉变量a和b,值传递方式捕捉其他所有变量[&,a, this]:值传递方式捕捉变量a和this,引用方式捕捉其他变量
c. 捕捉列表不允许变量重复传递,否则就会导致编译错误。比如:[=, a]:=已经以值传递方式捕捉了所有变量,捕捉a重复    
d. 在块作用域以外的lambda函数捕捉列表必须为空。
e. 在块作用域中的lambda函数仅能捕捉父作用域中局部变量,捕捉任何
非此作用域或者非局部变量都会导致编译报错。

mutable

我们先写一个简单的表达式:
在这里插入图片描述
可以看到,x和y是不允许被修改的,而且这里有一点小问题,我们等会儿一起说。
在这里插入图片描述
现在可以修改了,但是为什么实际没有修改啊?
在这里插入图片描述
现在又修改了。我们首先是可以看到的是当我们捕捉父作用域的参数的时候,在表达式内部其实是默认不允许我们修改捕捉到的变量的值的,所以这时候我们就可以使用mutable来改变这种性质,就可以修改了。

Lambda表达式的一些小知识点

1). 类型

首先我们看到这么一句:
在这里插入图片描述
Lambda是可以给一个变量的,那我们看看这个变量的的类型是什么:
在这里插入图片描述
这是在VS2019中的命名,我们看到它是一串乱码,这个乱码其实是uuid: link。
而在VS2022中它的命名是这样:
在这里插入图片描述
但是不管怎么样,它都是一个类,在C++中Lambda表达式的本质其实也是仿函数

2). 要注意的点

那还有一点:为什么这么做没有修改啊?
在这里插入图片描述
按照经验来说,这里其实是传值了,被捕捉到的x和y变量和外面的x和y已经没关系了:
在这里插入图片描述
那第二次修改后能修改成功了,那自然也是传引用了:
在这里插入图片描述
其实:
在这里插入图片描述
当我们捕捉引用的时候,不需要加mutable就可以修改捕捉的参数了,这是编译器做的特殊处理。

3). 本质

至于为什么说C++中Lambda表达式本质上就是仿函数那看下面这段代码:
在这里插入图片描述
不能说没有关系吧,简直是一模一样。都是重载()而已。

4). 类中的Lambda

还有在类中的Lambda是怎么样的:
在这里插入图片描述
很正常,其实也可以这样:
在这里插入图片描述
还有这个:但是和上面还是有区别的
在这里插入图片描述
有人可能就犯迷糊了,不是刚上面说了捕捉列表传值修改不了原数值吗?这就是混淆了,这里是捕捉的_aa和_bb吗?其实捕捉的是this指针,这里能直接使用_aa和_bb,的原因是编译器又做了特殊处理让它变得跟在成员函数中那么用一样。

6. 包装器

a. 引入

到现在,我们通过对象调用函数的方式已经有有三种了:函数指针,仿函数,Lambda表达式。
在这里插入图片描述
在这里插入图片描述
他们都有着属于自己的特点,以及不同时代语言的特点。所以在历史的开发过程(C/C++)中,那么一定会刚开始是函数指针,然后是仿函数,再是Lambda表达式。那么这样的代码流在市面上,导致了代码和接口的使用有了差异性,所以函数包装器(function包装器)就应运而生,它是一个类模板(使用了可变参数列表)

b. 使用

在这里插入图片描述
在这里插入图片描述

// 类模板原型如下
template <class T> function;     // undefined
template <class Ret, class... Args>
class function<Ret(Args...)>;
模板参数说明:
Ret: 被调用函数的返回类型
Args…:被调用函数的形参

c. 场景

那上面实际有什么用呢?我最近想自己写一个植物大战僵尸,其中关于植物的创建就是用了这个知识:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们看到运用多态和包装器的知识我们可以写出这样的代码(虽然不用包装器也可以)。而且这里也有了一个新知识:

成员函数比较特殊,要加一个类域和&

d. bind

bind是一个函数模板,它就像一个函数包装器(适配器),接受一个可调用对象
(callable object),生成一个新的可调用对象来“适应”原对象的参数列表。一
般而言,我们用它可以把一个原本接收N个参数的函数fn,通过绑定一些参数,
返回一个接收M个(M可以大于N,但这么做没什么意义)参数的新函数。同时,
使用std::bind函数还可以实现参数顺序调整等操作。

在这里插入图片描述
在这里插入图片描述
这种一般是用在网络部分(知识盲区了。。),其中的接口有很多参数,但是部分参数在一些场景中都是一个值,或者不同的人写出来的接口中参数顺序不太一样,就可以使用这个来修改,让自己使用更方便。

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

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

相关文章

一个神奇的Python库:Evidently,机器学习必备

Evidently 是一个面向数据科学家和机器学习工程师的开源 Python 库。它有助于评估、测试和监控从验证到生产的数据和 ML 模型。它适用于表格、文本数据和嵌入。 简介 Evidently 是一个开源的 Python 工具&#xff0c;旨在帮助构建对机器学习模型的监控&#xff0c;以确保它们的…

博客动态校验+静态校验二次开发方式

静态校验&#xff1a; 1&#xff1a;将需要静态校验的参数继承BaseReqeust类重写validate方法&#xff1a; 动态校验&#xff1a; 1&#xff1a;在需要校验的实现类上加&#xff1a; BizValidate注解 2&#xff1a;写一个校验类&#xff0c;方法命名规范为&#xff1a;需要校…

修改npm源码解决服务端渲染环境中localstorage报错read properties of undefined (reading getItem)

现象&#xff1a; 这个问题是直接指向了我使用的第三方库good-storage&#xff0c;这是一个对localStorage/sessionStorage做了简单封装的库&#xff0c;因为项目代码有一个缓存cache.ts有用到 原因分析&#xff1a; 从表象上看是storage对象找不到getItem方法&#xff0c; 但…

Android--Jetpack--数据库Room详解一

人生何须万种愁&#xff0c;千里云烟一笑收 一&#xff0c;定义 Room也是一个ORM框架&#xff0c;它在SQLite上提供了一个抽象层&#xff0c;屏蔽了部分底层的细节&#xff0c;使用对象对数据库进行操作&#xff0c;进行CRUD就像对象调用方法一样的简单。 二&#xff0c;角色介…

基于YOLOv8深度学习的路面标志线检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

docker容器-compose单机容器编排

目录 yaml文件使用的注意事项 yaml文件的基本数据结构 docker-compose单机容器编排 docker-compose的常用命令 安装docker-compose docker-compose部署nginx nginx文件 yml文件 docker-compose创建镜像和容器 docker-compose构建lnmp nginx文件 mysql文件 php文件…

华为组播配置案例

igmp-snooping主要用于生成二层组播表项&#xff0c;防止交换机全部接口都发组播报文 PC端配置&#xff1a; 组播源配置&#xff1a; R1 interface GigabitEthernet0/0/0 ip address 10.0.0.1 255.255.255.0 pim dm interface GigabitEthernet0/0/1 ip address 192.168.0…

UE5 C++(三)— 基本用法(生命周期、日志、基础变量)

文章目录 生命周期日志打印Outlog打印屏幕打印 基础变量类型FString、FName 和 FText&#xff0c;三者之间的区别 基础数据类型打印 忘记说了每次在Vscode修改后C脚本后&#xff0c;需要编译一下脚本&#xff0c;为了方便我是点击这里编译脚本 生命周期 Actor 生命周期官方文档…

年底总结-基于战略落地的年度经营计划

到了年底&#xff0c;今年不管经济如何&#xff0c;形势多么不好&#xff0c;这个月也要结束2023年了&#xff0c;在这个阶段最关键的是做好今年的总结以及明年的计划。 总结是为了更好地做明年的计划和形势的预判。 借用数据表作为工具&#xff0c;科学理性地对自身公司的经…

基于Java+Swingt学生信息管理系统

基于JavaSwing学生信息管理系统 一、系统介绍二、功能展示四、其他系统实现五、获取源码 一、系统介绍 1.用户登陆&#xff1a;在帮助按钮处&#xff0c;可以查看登陆账号及密码&#xff1a; 账号admin,密码123456 在未输入的情况下&#xff0c;会提示用户名不能为空&#xff…

广受好评的开源基础大模型最全梳理,你最钟意哪一个?

2023 年即将过去。一年以来&#xff0c;各式各样的大模型争相发布。当 OpenAI 和谷歌等科技巨头正在角逐时&#xff0c;另一方「势力」悄然崛起 —— 开源。 开源模型受到的质疑一向不少。它们是否能像专有模型一样优秀&#xff1f;是否能够媲美专有模型的性能&#xff1f; 迄…

C#实现MQTT over WebSocket

如何在网页端实现MQTT消息的发布和订阅&#xff1f; 实现MQTT功能&#xff0c;可以发布和订阅主题通过WebSocket协议将MQTT消息转发给对应的网页端 带着这个实现思路&#xff0c;采用C#控制台程序实现MQTT服务端功能&#xff0c;web端可以直接使用websocket插件与服务端双向通…

第7章 排序

前言 在这一章&#xff0c;我们讨论数组元素的排序问题。为简单起见&#xff0c;假设在我们的例子中数组只包含整数&#xff0c;虽然更复杂的结构显然也是可能的。对于本章的大部分内容&#xff0c;我们还假设整个排序工作能够在主存中完成&#xff0c;因此&#xff0c;元素的个…

计算机网络知识点

计算机网络中的OSI模型 OSI模型是指“国际标准化组织(SO)”提出的使各种计算机在世界范围内互通互联的网络标准框架简称开放系统互联参考模型 (OSI)。 七层模型&#xff1a;应用层、表示层、会话层、传输层、网络层&#xff08;IP协议、RARP协议、ARP协议、CIDR协议&#xff0…

kafka学习笔记--Topic 数据的存储机制

本文内容来自尚硅谷B站公开教学视频&#xff0c;仅做个人总结、学习、复习使用&#xff0c;任何对此文章的引用&#xff0c;应当说明源出处为尚硅谷&#xff0c;不得用于商业用途。 如有侵权、联系速删 视频教程链接&#xff1a;【尚硅谷】Kafka3.x教程&#xff08;从入门到调优…

docker小白第五天

docker小白第五天 docker的私有库 有些涉密的信息代码不能放在阿里云的镜像仓库&#xff0c;因此需要构建一个个人内网专属的私有库&#xff0c;将镜像或者容器代码进行推送保存。 下载镜像docker registry 执行代码docker pull registry&#xff0c;用于搭建私服前的准备。…

Linux系统log日志简单清理

系统空间告急 清理log日志 找出当前目录中文件最大的10个文件&#xff1a; cd /var/log du -s ./* | sort -nr | head 系统日志log文件&#xff1a; ll -h /var/log/journal 只保留100MB的日志 journalctl --vacuum-size100M 系统暴力爆破SSH日志&#xff1a; ll -h /var/lo…

初级数据结构(六)——堆

文中代码源文件已上传&#xff1a;数据结构源码 <-上一篇 初级数据结构&#xff08;五&#xff09;——树和二叉树的概念 | NULL 下一篇-> 1、堆的特性 1.1、定义 堆结构属于完全二叉树的范畴&#xff0c;除了满足完全二叉树的限制之外&#xff0c;还满…

SolidWorks二次开发 C#-读取基于Excel的BOM表信息

SolidWorks二次开发 C#-读取基于Excel的BOM表信息 问题点来源解决方案及思路相关引用链接 问题点来源 这是一位粉丝问的一个问题&#xff0c;他说到: 老师&#xff0c;请问Solidworks二次开发工程图中"基于Excel的材料明细表"怎么读取里面的数据&#xff1f; Ps:这…

leetcode刷题日志-383赎金信

思路&#xff1a;分别用两个map记录ransomNote和magazine中的字符以及出现的次数。最后遍历记录ransomNote的map&#xff0c;如果ransomNote的map中出现的magazine的map中没有出现或者出现的次数小于ransomNote的map则返回false&#xff0c;否则返回true&#xff1b; class So…