自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(53)
  • 收藏
  • 关注

原创 Cherno C++ P64 多维数组

我们还记得,如果是二维的话,我们本身会定义一个指针数组,那么当我们扩展到三位的时候,我们需要定义一个指针数组的数组,也就是我们需要一个数组,也是装满指针的,但是其中的每一个指针指向的是一个指针数组,然后每一个指针数组里面的每一个指针再指向一个真是存放我们数据的数组。C++当中的二维数组,可以理解为一个数组的集合,也就是数组的数组。而我们知道如果想管理一个数组,通常使用的是指针,那么数组的数组也就变成了一堆指针的数组,每一个指针再单独指向一个array,而这也就是我们在C++当中实现多维数组的一个思路基础。

2025-03-09 14:44:43 920

原创 P63 C++当中的计时

但是对于不同的平台,计时方式可能有所区别,如果真的想要非常精准的计时,通常我们需要使用操作系统自带的计时器。有的时候我们需要对于运行的某段代码进行计时,有的时候我们想要让某件事情在某个时刻发生,或者是有的时候我们需要进行基准测试,都需要使用到计时。但是这样使用,我们会发现看起来也太麻烦了,我们希望能不能有一个相对比较简单的道具,可以直接在我们希望的函数开头加上这个计时器,那么在函数结束的时候就可以给我们打印出时间,这样就很nice。我们可以看到,很顺利的打印出了用时,这个就很赞。

2025-03-07 23:42:51 408

原创 P62 线程

它的含义是,我们会在主线程上做一个阻塞,让主线程暂时不会继续运行,一直等到我们的worker线程运行完毕,然后才会接着运行。这篇文章我们来讲一下线程。截止到目前,我们的代码都是在单线程上运行的,现在看起来没有什么问题,但是目前所有的计算机几乎都不只有一个逻辑线程,所以如果我们一直使用单线程运行,这样的话效率会很低。举个简单的例子,我们有一个等待接收用户指令的函数,那么在等待用户输入指令的过程当中,我们有可能希望程序执行一些其他事情,那么我们就需要有一条线程在等待用户,而另一条线程在执行其他事情。

2025-03-07 22:57:38 429

原创 Cherno C++ P61 C++当中的命名空间

那么在我们现实当中,其实这种有相同命名的函数/变量的需求还是很多的,因为很多函数可能功能就是类似的,命名的时候也就是类似的。在C当中,是没有命名空间的,所以如果在C当中写一个库,需要用这个库的名字来作为前缀或者后缀,以此和其他库里面的函数区分开。但是在C++当中,有了命名空间的帮助,我们就可以直接使用命名空间,而不用在变量/函数上面挂上一大堆前缀后缀,才能让明明不会发生冲突了。命名空间的操作符就是::,这个我们在之前已经见了很多次了,这个符号的作用就是说明我们在使用这个命名空间内的变量。

2025-03-03 22:56:02 246

原创 Cherno C++ P60 为什么不用using namespace std

我们在使用std::的时候,其实表明的含义是这些是来源于一个名为std的命名空间。因为我们输入的对象是一个const char*类型的变量,虽然Apple当中的Print其实也能用,但是它需要进行一次隐藏的类型转换,转换为std::string,那么和Orange当中的Print一比较,编译器就会选择不需要类型转换的Orange当中的函数了。但是需要注意的一点是,在使用using namespace的时候,一定一定要控制using的适用范围,在一个小作用域内,或者是在一个文件里那是最好不过的。

2025-03-03 22:26:23 526

原创 Cherno C++ P59 lambda函数

从某种程度上来讲,相比于一个正儿八经的函数,我们更应该把它看作是一个变量,而且只要在可以使用函数指针的地方,我们就可以使用lambda函数,那么这么看来确实就更像一个变量了。但是如果我们直接修改会发现一个问题,那就是我们原来定义的函数指针,是没有传递这么个说法的,那么我们这么一修改,新的lambda函数类型就和我们定义的函数指针类型不同了,而且没有合适的转换方式,因为我们一开始定义的函数指针是没有什么捕获功能的。这样的话我们获得的就是values当中大于3的值所在的位置,然后我们打印它,就会发现值为5。

2025-03-01 17:40:08 299

原创 Cherno C++ P58 函数指针

为什么我们要使用函数指针?举个例子,比如我们有一个vector类型变量,我们想要对它内部的每一个变量依次循环做一些操作,我们当然可以选择写一个循环,然后每个变量应用一下对应的函数,但是我们也可以通过传递该函数的指针来进行操作。在我们给出的例子当中,我们有一个打印int的函数,同时有一个处理vector且接受函数指针的函数,通过把打印int的函数指针传递进去,我们就可以不断地打印vector里面的值,而且更好的一点是,我们如果有不同的函数,也可以如法炮制的传递进去,而不需要更改ForEach函数的内容。

2025-03-01 14:29:45 347

原创 Cherno C++ P57 Standard array处理静态数组

很明显,我们只有在debug模式下才会进行边界检查并打印错误信息,但是在release模式下,array的操作是与普通数组完全一样的,这也带来了array很高的使用效率,所以尽可能使用array是很好的选择,因为一方面它可以为我们提供内存检查与长度信息,另一方面在release版本中又不会影响使用新能。其次C++当中也确实给我们提供了一些可以用来处理静态数组的办法,之前已经介绍过的包括原始数组和STL vector,而C++ library当中还为我们提供了另一个,就是array类型。

2025-02-23 12:42:17 405

原创 P56 auto类型

最后需要注意的是,auto只能替代类型名,auto无法替代const或者是&符号,所以如果想要使用引用需要写明auto&,不然的话也会被当作是copy。另外一个经常使用auto的情景时,如果我们有一个非常长的变量类型名,那么使用auto来替代就非常方便了。我们可以看到,迭代器it的类型名非常长,而且并不是那么有意义,或者说是,并不是非常关键。我们可以看到,两个类型其实不同的变量我们都可以用auto来修饰,如果我们把鼠标放到auto上面,会看到这个变量的真是类型。这样一下子就整洁太多了。

2025-02-23 12:01:06 299

原创 Cherno C++ P55 宏

如上述代码所示,我们可以在debug模式下让LOG函数真的为我们输出一些东西,但是在release模式下,LOG就不代表任何代码了,也就是说切换到release时,LOG处都会变成空白,宏自动的为我们删除了在release时需要被删除的代码,这一点是非常nice的。但是这样使用也是有一点问题的,因为有的时候我们不想使用某个宏了,那我们还得去删除,就很麻烦,最好的情况是给宏赋一个值,然后我们不想使用宏的时候,可以直接修改这个宏的值,那么这个宏就被禁用了。其实接触过大型项目的朋友可能都被诡异的宏折磨过。

2025-02-16 23:19:29 341

原创 Cherno C++ P54 内存:栈与堆

在我们程序启动的时候,我们的操作系统会调一部分RAM内存分配过来,当我们使用malloc时,会启动一个叫做free list的东西,来检查内存的空闲状况。对比一下这两个地址,我们就会发现,它们的距离实际上非常近,这还是因为在debug的模式下,编译器会自动帮我们填充一些safety guard,实际上它们就应该是紧挨着的。栈分配是一个CPU指令,而堆分配是一系列工作,这是这两者最大的区别,同时也导致了两者性能上的差别,堆分配的速度会明显更慢。堆相对而言,空间更大一些,也是预定义好的,但是堆可以增长。

2025-02-16 20:36:57 815

原创 Cherno C++学习笔记 P53 模板

它的影响方式是,在我们预处理之后,实际编译之前,模板类会根据我们定义和使用它的方式,帮我们给这个函数写出来,然后我们再调用编译器帮我们写出来的这个函数。但是如果在比如我们的日志类当中,我们要打印的东西不仅仅有string类型,可能还会有其他类型,比如int/float/double等等,那么我们就得把这个简单的函数换一个类型,一遍一遍的写一遍,这个听起来就很费劲了,而更离谱的是,如果我们想要修改一下这个Print函数,那么我们每一个类型对应的函数都得修改一下,想一想这个工作量就很让人难受。

2025-01-16 00:28:03 710

原创 Cherno C++学习笔记 P52 处理多返回值

从技术上来讲,这有可能是最理想的方式,因为没有复制发生,我们直接修改了在函数外面的变量,所以其实是可以最快的。同样的,这也是一种输出不同类型变量的风格,在给变量起名字的时候,我们可以给预计要输出的变量添加一个out前缀,来表明这些其实是我们这个函数的输出变量。除了这个方法之外,还可以用另一个方法,这个也是很多实践场合会使用的办法,就是把函数改成void,然后输入变量改成引用,这样我们就可以用修改引用的方法修改外面已经定义好的量,这样就实现了我们函数修改变量的功能。这个其实是很混淆的,我们是不知道的。

2025-01-15 00:02:45 622

原创 Cherno C++学习笔记 P51 创建并使用库

在一开始的时候,我们需要注意,我们生成一个解决方案之后,其实可以在解决方案里面添加很多项目,这个之前还没有尝试过,所以这里我们可以试一下该怎么做。我们在Engine里面添加一个print函数,就很简单的打印一个hello world,然后我们在设置-常规当中把Engine设定为输出类型是.lib,也就是我们会把它编译为一个静态库。然后我们在解决方案当中添加另一个项目Engine,意味着我们有一个游戏解决方案,然后我们把一个游戏引擎项目添加到里面来。如图所示,我们就可以为我们的解决方案添加多个项目啦。

2025-01-09 23:17:06 347

原创 Cherno C++学习笔记 P50 C++当中的动态库

这是因为在我们的dll文件里面,可能有很多的函数,我们需要知道头文件里面每一个函数的位置在哪里,但是因为我们在运行时才会加载进来,所以提前我们是不知道它们的位置的,这就需要一个存储着这些函数的指针的库来告诉我们的程序,我们这些函数的位置在哪里,那么这些指针就会存放在一个dll.lib文件当中。这两者的区别是,静态链接发生在编译的时候,会把静态库当中的内容直接插入到exe/dll文件当中,所以编译器会进行一定的优化,因为我们的linker对于我们要塞进来的内容会有一些提前的了解。

2025-01-06 23:03:22 275

原创 Cherno C++学习笔记 P49 C++中使用静态库

这里需要注意的一点是,在include的时候,这里无论是使用<>还是""都是可以的,因为我们的路径已经被添加到解决方案当中了。但是如果我们想要生成,是会发生错误的,因为我们其实没有告诉编译器我们的函数定义在哪里,那这就需要我们再把函数定义的内容包含进来了。随后我们还要告诉编译器,具体我们添加的是哪个库,在这里面我们需要把我们用的库添加进去。打开然后选择32/64位的适合Windows的预编译库,选择多少位的并不取决于我们目前计算机是多少位的,而是取决于我们要生成的那个目标应用要在多少位的平台上使用。

2025-01-05 00:40:19 848

原创 Cherno C++学习笔记 P48 如何让vector运行的更快

vector在我们添加新元素的时候,因为内存不够,所以会不断地进行寻找新的足够的内存——把原来的数据全部拷贝到新的内存里面——删除原有的数据这样一个工作,不断分配新内存的过程费时费力,拖慢我们的速度。主要的来源有两个,第一个是如果我们在main当中进行push_back,那么实际上我们做的事情是先在main当中创立一个变量,然后复制粘贴到了我们的vector当中去,这是一个可以优化的点,如果我们可以直接创建在vector里面,是不是就可以省去这样一个步骤了?次复制构造函数,这个确实是不能接受的。

2024-12-31 17:44:38 494

原创 Cherno C++学习笔记 P47 动态数组Vector

比如如果我们有一个长度为5的array,我们想要一个长度为6的,那么只能新建一个array,但是对于Vector,我们可以直接在后面多添加一个格子,那它就有6这么长了。它的办法就是在我们需要添加新的格子的时候,去寻找新的更长的内存块,然后直接把原来内存里面的内容复制粘贴过去,然后再删除掉原来的内存里面的内容。接下来我们看看vertex的一些基本功能,首先是在后面添加一个新的项,通常我们会使用的是push_back方法,也是非常常用的vector的方法,功能就是给我们的vector末尾再添加一项。

2024-12-31 16:56:40 335

原创 Cherno C++学习笔记 P46 箭头运算符

也不难理解,我们首先将一个空指针强制转换成Vector3指针,也就是说我们让这个Vector3指针指向了0位置,然后我们取x,再对它取值,就是x相关于Vector3指针的位置了,至于转成int那无非就是方便输出给我们看。很简单的一个向量类,然后我们想要获取变量x,y,z关于我们对Vector3指针的偏移量,该如何获得?也就是说,如果我们有一个Vector3指针,它会指向某一个位置,但是其中的成员变量x,y,z也有自己在内存中的位置,那么成员变量的位置相对于struct指针指向的位置差了多少?

2024-12-24 23:12:52 704

原创 Cherno C++学习笔记 P45 拷贝与拷贝构造函数

但是我们需要注意的是,复制这件事情是非常花费时间和内存的,所以在没有必要的情况下,我们应该尽可能避免不必要的复制,尤其是如果我们只是读取,或者说是希望能够影响输入的变量本身的情况下,就更不希望是复制了。但是我们需要指出的一点是,如果函数参数只是变量本身,那么我们在调用函数的时候也会发生拷贝,而这在很多时候是会非常浪费时间的,因为我们在不想改变变量的值的情况下,复制是没有任何意义的,只会导致效率的降低。所以如果我们对其中一个指针指向的内容进行了修改,那么另一个指针指向的内容也会被影响,因为这是相同的内容;

2024-12-20 23:17:35 837

原创 Cherno C++ 学习笔记 智能指针

因为如果我们有两个unique指针,指向了同一片内存,那么当我们删除掉其中一个指针的时候,这部分内存就已经被释放出来了,那么第二个指针就没有任何意义了,所以我们不能复制unique指针,这也是为什么这种智能指针被称为unique。我们可以通过把两个指针放在不同的作用域里的方式来看一下效果上的不同,如下所示,我们可以把断点放在最后一句话进行调试,可以发现在出了内层的作用域之后,析构函数并没有被调用,说明这部分内存并没有被释放。所以只有当所有的sharedPtr全部过期之后,才会迎来指向的目标的内存的释放。

2024-12-20 21:55:13 1043

原创 Cherno C++学习笔记 P43 对象生存周期

因为虽然new Entity是在堆上分配内存,但是ScopedPtr类是在栈上分配的内存,在离开作用域之后,它就会调用自己的析构函数,而它的析构函数,我们自己写的,刚刚好又是释放new Entity所分配的内存,所以我们可以不用再额外去写delete,就实现了离开作用域之后自动释放new分配的内存。我们都知道,在为变量分配内存的时候,我们可以选择栈上分配,也可以选择堆上分配,由于在堆上分配需要我们手动清理内存,所以相当于我们可以自己决定这个变量的生存时间,因此我们主要了解栈上对象的生存周期。

2024-12-19 14:41:08 717

原创 Cherno C++学习笔记 P42 this关键字

当然需要注意的一点是,我们必须先实例化,然后才能使用this指针。这个时候我们把鼠标放在this上面,我们会看到this的类型是const Entity*, 此时它就成为了一个不能改变内容的指针,当然也是符合我们的预期的,因为我们预期这类函数就是不能修改类当中的变量的。如果我们把鼠标放在this上,可以看到this的类型,就是普通的Entity*类型,所以我们可以直接拿来给Entity*类型的变量赋值,当然也可以赋值给const类型的指针,但是我们通常不这样做,因为这样做的话就意味着我们无法修改了。

2024-12-19 00:51:28 558

原创 Cherno C++学习笔记 P41 运算符与重载

C++当中的运算符operator是代替函数执行某些事情的符号,除了我们熟悉的加减乘除等运算符之外,还有一些特殊的,比如new/delete也是操作符,甚至于逗号“,”、“[]”和“()”其实都是operator运算符。在C++当中,我们对于运算符有完全的控制权,我们在重载运算符的时候有着极高的自由度,当然这也是C++的特点。但是我们需要注意的是,运算符重载不能随随便便的使用,只有在涉及某些数学量的加减乘除等操作的时候,我们去重载运算符才能够比较有意义。如果没有特别的需求,我们最好不要进行运算符的重载。

2024-12-18 00:28:42 546

原创 Cherno C++学习笔记 P40 隐式转换与explicit关键字

因为我们的字面量其实是一个const char[]类型,那么它转换到string是一次类型转换,而string到Entity又是一次类型转换,这样就会连续发生两次转换,但是我们知道,编译器只接受一次隐式转换,所以我们需要手动进行一次强制类型转换,把const char[]转换为string。我们通过这样的隐式转换,可以大大简化代码,这个是一个有点,但是也带来了问题,就是代码看起来并不是很清晰,会感觉乱七八糟的,所以通常我们还是要用常规的初始化对象的办法,反正也没有什么损失对吧。

2024-12-17 23:54:07 622

原创 Cherno C++学习笔记 P39 new关键字

比如当我们写出new int的时候,就是在给我们分配了4个byte的内存,而且是连续四个byte上面的。所以new的主要目的,就是为我们找到足够大的内存块,然后返回指向这一部分内存的指针。如果是使用Java或者是C#的朋友,对于new关键字应该是很熟悉的,但是在C++当中,new所代表的含义完全不同了,其功能也是很深奥的。当我们使用C++的时候,我们希望的肯定是对于内存性能的优化以及掌握一切的快乐,尤其是到了2024年,在有这么多语言可以供我们选择的情况下,如果不是为了优化性能,谁又愿意去选择C++呢?

2024-12-17 13:20:11 695

原创 Cherno C++学习笔记 P38 创建并初始化C++对象

其次,在栈中变量有着固定的作用域,而变量的寿命也是由作用于决定的,离开了作用域,变量的寿命就结束了,变量也会跟着被销毁。那么如果我们的对象所占用的空间非常大,或者我们希望对象有更长的寿命,应该怎么办?比如如果我们这么做,那么我们会得到错误,未定义的标识符e,因为离开了作用域,e根本就不存在了,被销毁了,所以这么写就是错误的。我们定义一个空的类,需要注意的是,即使我们的类里面什么都没有,也要占用至少一个字节内存。new会返回建立在堆上的变量的位置,所以我们需要定义一个相关的指针,然后使用指针操作。

2024-12-14 00:44:46 554

原创 Cherno C++学习笔记 P37 三元运算符

前面是一个判断,判断s_level和5之间的大小关系,如果是true的话,取:前面的值;我们在这里用了if else语句来给s_speed变量赋值,根据s_level的高低,s_speed会有不同的值。对于性能上来讲,如果是使用string类型的话,采用三元运算符通常会比if else更快一些。对于可读性这个角度,这个写法其实是见仁见智的,因为如果习惯了这种写法,有可能就会觉得这样无所谓。而且三元运算符返回值有一个优化的算法,所以也会更快一些。我们可以看到,我们需要先创建一个空字符串,然后再覆盖掉它。

2024-12-14 00:09:56 627

原创 Cherno C++学习笔记 P36 初始化类成员

这样做首先是一种更加简洁的语言风格,因为我们想象一下,如果这个类有十多个甚至更多成员变量,那我们可能得写上十几行几十行初始化,看起来就很麻烦,但是如果使用列表化初始化,那就没有这个问题了,所以听起来是不错的。我们可以看到,我们使用了两个构造函数,一个是调用了默认的构造函数,还有一个调用了输入一个string的构造函数,然后我们打印了它们的名字变量,分别是Unknown和Cherno,没有问题,很棒。很好,这样的话我们只初始化了一个Print类型的变量,所以如果使用列表化初始化方法,会提高我们的运行效率。

2024-12-13 23:39:46 523

原创 Cherno C++学习笔记 P34-35 const与mutable

相对应的,指针变量本身,所储存的这一串地址本身,就是可以进行修改的了。那么这个时候,关键的地方来了:如果我们在使用一个类的实例的常引用的时候,如果我们使用了一个非const方法,那么我们就有可能通过这个方法改变我们这个对象的值,那么就会发生报错。这样连个三个const,表明的是我们这个函数是一个只读函数,而且它返回的指针是一个不能修改它的指向,也不能修改它指向的值的指针。因为我们输入的是const在*e前面,所以指针指向的对象是不能被改变的,如果GetX函数没有const关键字,那么就是会报错的。

2024-12-12 01:09:32 1120

原创 Cherno C++学习笔记 P33 字符串的字面量

所以对于字面量,我们一般都用const char*,如果真的想要对其进行修改,那么需要使用数组而不是指针,这个时候我们相当于是把这个字面量复制了过来,复制到了我们的数组中,那么当然就可以修改了。我们可以看到,分别移动了目标的字符串和常量到对应的寄存器,然后通过mov指令分别进行复制,最后我们设定操作次数为7次,并使用rep movsb命令,将rsi当中的内容一个字节一个字节的搬运到了rdi当中,这样通过复制,我们完成了用字面量给数组赋值的操作。这种写法被称为是“未定义行为”,这是很危险的,所以不要去尝试。

2024-12-09 23:41:19 1325

原创 Cherno C++学习笔记 P32 字符串

所以为了能够表示更多的语言,我们有很多其他的编码方式来进行处理,比如utf_16,允许我们用两个字节,16位来表示一个字符,那么就可以有。这样我们可以看到,输出的长度是7而不是我们看到的6,这是因为我们在最后还有一位空字符,这个被称为空终止符,是编译器自动加上来的。需要注意的一点是,如果我们定义好了一个字符串,就意味着我们没有办法再改变它的长度了,如果想要更长的字符串,我们只能删除掉重新写一个。那么会涉及一次字符串的拷贝,这个是会非常浪费时间的做法,因为拷贝字符串是很慢的,所以会导致性能的降低。

2024-12-07 22:36:37 1010

原创 Cherno C++学习笔记 P31 C++数组

可以看到,在这个数组存储的位置上,我们有连续五个占有4个字节的int变量2,这也就意味着数组在存储数据的时候是进行的连续存储,而且看起来好像把一整个20字节的内存分成了5份,但是实际上并没有,只是看起来是这样。这里我们来讲一下C++的数组,可能在我们学习的C++教程当中,很少有这么晚了才讲到数组的,但是这也是我很喜欢Cherno这个C++教程的原因之一,就是他并不急于把一些其他教程里面很早就介绍出来的概念马上就端出来,而是前面做好了足够的基础铺垫之后才会进行深入的介绍。当然这需要一定的开销。

2024-12-07 17:21:31 858

原创 Cherno C++学习笔记 P30 C++的类的可见性

实际上对于CPU来说,它是不知道哪个变量是public哪个变量是private的,定义这个东西不会影响到我们程序运行的性能。但是需要注意的一点是,可见性是纯粹的语言当中的东西,实际上它对于内存,程序运行速度等等是没有任何影响的,它单纯的是为了我们的代码可读性更强,能够帮助我们写出更好的代码以及组织代码。如上所示,如果我们这么写,那么编译器就会给我们提前警告,我们在main当中是无法访问到e的X和Y变量的,能访问这些变量的只能是类当中的方法,即使是这个类的子类,也不能访问这个类的private变量。

2024-12-07 15:08:06 547

原创 Cherno C++学习笔记 P28-29 虚函数与纯虚函数

因为比如有这样一个函数,它接受某种类型,而且希望这个类型一定会有某种方法,因为它会调用这个方法,那么我们只需要定义一个包含有这个方法作为纯虚函数的接口类,然后我们使用其它类来继承这个类,实例化这个方法,再把实例化的对象传入到这个函数中,就完成了我们的设计目标。在之前的例子当中,我们在父类中定义了虚函数,说明这个虚函数有了默认定义,但是有的时候我们不希望它有默认定义,我们希望这个函数必须由子类实现,那么我们就可以把父类中的这个函数改为纯虚函数,这也是C++当中的一种。答案是可以的,我们把这类函数成为。

2024-12-04 23:37:19 858

原创 Cherno C++学习笔记 P27 类的继承

通过类的继承,我们可以有一个具有基本功能的父类/基类,然后从这个父类派生出许多子类,形成一个有层次的相关联的类的集合。有了这个功能之后,我们在定义不同的类的时候,可以把所有的公共代码都放入到同一个父类当中,然后我们具体写子类的时候直接从父类继承就可以了。然后我们需要一个Player类,用来表示玩家,同样的,玩家类也需要位置信息和移动功能,这个和Entity类是很相似的。可以发现,我们的程序正常的运行了并且输出了结果,尽管我们函数期待的是一个Entity,但是输入的却是一个Player。

2024-12-03 23:42:53 597

原创 Cherno C++学习笔记 P25 26 构造函数与析构函数

不论这个对象是不是new出来的,都可以使用析构函数。其实C++本身的类是给我们内置了一个构造函数的,但是默认构造函数里面是什么都没有的,可以认为默认构造函数的函数体是空的,所以一定要自己手动初始化,这个和很多其他语言是有所不同的。可以看到的是,我们输出的值是一个不知道从哪里来的随机数,而且如果我们选择不调用函数,而是直接在main函数中访问这个实例化对象的变量,还会产生未初始化的报错。当然,目前我们是在栈上实例化一个类,如果我们是在堆上实例化一个类,也就意味着使用new关键字,那么我们还是会调用构造函数。

2024-12-03 23:07:44 509

原创 Cherno C++学习笔记 P24 枚举

比如说我们有一个标注状态的变量flag,而这个flag只能取值为0或者1,我们当然可以直接写这样一个变量出来,但是这也就意味着flag还可以取其他的值,这回给我们的代码带来一定的风险,因为我们只想这个flag取0或者1,其他值意味着无效。这样做有一个很明显的好处,就是代码看起来更加整洁了,而且我们将A,B,C这三个变量进行了分组,不至于我们写了一堆变量,散落的到处都是,到时候都不知道谁是谁了。我们可以看到,里面有一个LogLevel,我们希望这个值只能取到0,1,2,这正好是一个可以用枚举类型替代的地方。

2024-12-03 13:21:58 284

原创 Cherno C++学习笔记 P20 P21 P22 static关键字

还需要注意的一点是,在我们定义这两个变量的时候,这个用法看起来很像命名空间的定义方法,虽然类并不是命名空间,不过当使用的是static变量的时候,这两者确实有一点类似的地方,就是在这个类名/命名空间名下面,就只有这样一个变量,这样一块内存。但是有的时候,我们希望这个变量可以活得更久一点,将来还有可能用到,那么我们就需要添加static关键字。这里需要我们像定义变量一样定义一下x和y,不然的话会报错,那么运行这个程序,我们会发现输出的结果并不是(4,8),而是(10,20),这个也证明了我们的观点,那就。

2024-11-28 01:11:05 449

原创 Cherno C++学习笔记 P20 写一个自己的日志类

很简单,因为当我们写一些很大很复杂的程序的时候,如果出了一些问题,我们去找其实是很难的,因为一方面编译器虽然会给我们一些错误信息,但是很有可能牵一发动全身,来回改反而越改越错(这一点参与过大项目编程的应该都深有体会==),再一个就是,真有可能编译器编译通过了,看起来啥问题没有,但是实际上输出根本就不是我们想要的输出,里面逻辑本身就是错了的,是不符合我们设计的功能的,这种的找起来更是难如登天了。再一点,对于类的成员变量,我们倾向于使用一个m_前缀将其区分开来,表示这个是我们类的私有成员变量。

2024-11-27 00:10:32 284

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除