
C++学习笔记
文章平均质量分 50
个人记录C++知识点的笔记
如果能帮到别人那就更好了
北原春希_
喜欢陈奕迅
展开
-
移动语义 in C++【C++学习笔记】
89.移动语义 in C++当我们知道左值和右值,左值引用和右值引用后,我们可以看看它们最大的一个用处:移动语义🍅移动语义概述移动语义让事情变得简单,移动语义本质上允许我们移动对象。这在C++11前是不可能的,因为C++11引入了右值引用,这是移动语义所必须的其基本思想是:当写C++代码时,很多情况下,我们不需要或者不想把一个对象从一个地方复制到另一个地方,但又不得不复制。例如,把一个对象传给一个函数,那么它就要获得那个对象的所有权,我别无选择,只能拷贝。而当想从一个函数返回一个对象时也是如原创 2022-05-15 09:51:06 · 200 阅读 · 1 评论 -
左值与右值 in C++【C++学习笔记】
85.左值与右值 in C++🍅左值和右值是什么现在又很多人称左值为有地址的值,因为它们是有地址的如果要给一个具体的定义左值是由某种存储支持的变量右值是临时值int i = 10;如上表达式有两部分,左边和右边左值绝大多数时候在等号左边,右值在右边(但这并不总是适用的!)可以将右值赋值给左值,但不能给一个右值赋值(比如给10赋值)int i = 10;int a = i;在这里等号左边是左值,右边同样是左值,所以才说等号右边就是右值的说法是错的❌右值不仅仅是字面量,原创 2022-05-14 10:10:12 · 201 阅读 · 0 评论 -
追踪内存分配的简单方法 in C++【C++学习笔记】
84.追踪内存分配的简单方法 in C++知道你的程序什么时候分配内存,特别是堆内存,是很有用的。弱知道程序在哪里分配内存,便有可能减少它,从而运行更快,因为在堆上分配内存并不是最好的做法,尤其是在性能关键的代码中此次所探讨,展示的所有东西,都可以很容易的插入到你现有的应用程序中!记住的知识没有应用就是无用的!🍅追踪内存的方法论简单例子#include <iostream>struct Object { int x, y, z; };int main() {原创 2022-05-12 13:36:41 · 594 阅读 · 0 评论 -
小字符串优化 in C++【C++学习笔记】
83.小字符串优化 in C++在编程语言中,字符串的名声比较负面,慢的众所周知(悲),字符串实在是有太多负面影响了,移除字符串后程序的速度显著提升但是又不能抛开字符串单做事,字符串又是很重要的但无所谓,今天关注的是:C++标准库中如何优化小字符串🍅什么是小字符串优化小字符串(即不是很长的字符串),它们不需要堆分配,可以只分配一小块基于栈的缓冲区而不是堆分配的小字符串的实际定义长度由使用的C++标准库而变化,如VS2019中,小字符串的长度要小于等于15,即如果有一个这样的小字符串,它就不原创 2022-05-11 18:47:56 · 786 阅读 · 0 评论 -
五分钟了解单例模式 in C++【C++学习笔记】
82.单例模式 in C++今天讨论的不是c++的语言特性,而是一种设计模式,即单例模式🍅单例模式是什么单例是一个类的单一实例,而单例模式是指打算那个类或者结构体只有一个实例💡💡💡C++中的单例只是一种组织一堆全局变量和静态函数的方法🍅为什么要关心单例模式(为什么要用单例模式)在处理数据时一方面,如果你是有一个对象的单一实例,那么只会有单一的数据集,然后可能有一些功能而另一方面,我们有代表数据的类成员变量,我们有成员函数,代表的是对特定的数原创 2022-05-11 12:55:45 · 329 阅读 · 0 评论 -
如何让C++字符串更快 in C++【C++学习笔记】
80.如何让C++字符串更快字符串实际上是字符数组,所以对于string的主要问题,可能就是字符串格式化以及字符串的操作,这是因为它们都要分配内存🍅概述问题之前说过内存分配在堆和栈上的区别和建议:能分配在栈上就别分配到堆上,因为把内存分配到堆上会降低程序的速度。然而,std::string和它的很多函数都喜欢分配在堆上,这实际上并不理想#include <string>原创 2022-05-09 20:49:06 · 555 阅读 · 0 评论 -
如何让C++运行的更快 in C++【C++学习笔记】
79.如何让C++运行的更快 in C++这次的主题是:如何通过多线程来提高性能此次的多线程是来源于C++11的std::asnycasnyc的意思的 异步🍅std::asnyc用法首先要包含头文件#include <future>伪代码演示如果要加载一个文件里所有的东西,则可以用下面的for循环/*for (遍历一个文件) { 加载一个东西}*/for (const auto &file : meshFilepaths) { m_Meshes原创 2022-05-09 19:35:45 · 403 阅读 · 0 评论 -
如何储存任意类型的变量 in C++【C++学习笔记】
78.如何储存任意类型的变量 in C++前排提示,这个东西是C++17的新特性,需要设置成C++17才可使用今日的主题即为:std::any🍅std::any的使用std::any的使用非常简单首先要包含头文件#include <any>,并且确保是C++17#include <iostream>#include <any>int main() { std::any data; //亦可以std::any data = std::m原创 2022-05-08 18:41:57 · 932 阅读 · 0 评论 -
单一变量存放多种类型的数据 in C++【C++学习笔记】
77.单一变量存放多种类型的数据今天的主题是:如何在一个变量中存储多种类型的数据(这是一个C++17的特性)如何做到呢?要用到一个叫**std::variant**的东西(variant意思:变种,变形,各种各样的,易变的)🍅概述variant它和option很像,它的作用是让我们不用担心处理确切的数据类型,只有一个变量,之后我们在考虑它的具体类型故我们做的就是指定一个叫std::variant的东西,然后列出它可能的数据类型std::variant允许你列出所有可能的类型,然后你可能决定它将原创 2022-05-07 16:08:53 · 1200 阅读 · 0 评论 -
如何处理optional数据 in C++【C++学习笔记】
76.如何处理optional数据 in C++当我们的数据可能存在,也可能不存在的时候会发生什么呢?std::optional是C++17的新东西,用于检测数据是否存在or是否是我们期盼的形式,用于处理那些可能存在,也可能不存在的数据or一种我们不确定的类型在老处理方法中可以用返回引用的bool值来判断是否数据存在#include <iostream>#include <fstream>std::string ReadFile(const std::string原创 2022-05-07 10:58:37 · 808 阅读 · 0 评论 -
结构化 in C++17【C++学习笔记】
75.结构化 in C++17今天的主题:结构化绑定,只针对C++17结构化绑定是一个新特性,让我们更好的处理多返回值(曾有一回谈过如何处理多返回值,当时是用了结构体去处理,而这个结构化绑定就是在这个的基础上拓展的一种新方法,特别是处理元组,对组(pairs)以及返回诸如此类的东西🍅没用结构化前的应对多返回值先看以前应对多返回值的方法#include <iostream>#include <string>#include <tuple>std::t原创 2022-05-06 18:39:39 · 208 阅读 · 0 评论 -
基准测试 in C++【C++学习笔记】
74.基准测试 in C++你写了一段新代码,像把它的性能和你过去做的方法做一个比较,看看谁更快。而在C++中则有很多不同的方式来实现。如此,如下讨论的便是如何实际测量C++代码的性能(Cherno的观点和方法论)#include <iostream>#include <memory>int main() { int val = 0; for (int i = 0; i < 1000000; i++) { val += 2;原创 2022-05-06 15:48:24 · 710 阅读 · 0 评论 -
dynamic_cast in C++【C++学习笔记】
73.dynamic_cast in C++🍅概述当我们想要做特定类型的类型转换时,有C的方式,也有C++的方式C的方式就是类似于(int)a这般转换而C++的方式就是使用比如static_cast, const_cast的转换,dynamic_cast亦是如此dynamic_cast是作为一种安全机制提供给我们的转换类型方式,它做了额外的工作来确保我们实际的类型转换是有效的类型转换dynamic_cast更像一个函数,认识到这点很重要。它不想编译时进行的类型转换,而是是在运行时计算,所以会原创 2022-05-06 10:42:30 · 189 阅读 · 1 评论 -
预编译头文件(pch) in C++【C++学习笔记】
72.预编译头文件(pch) in C++一个很多人都知道但没有用过的东西。因为预编译头文件在大项目中很有用,但在个人的小项目和练习中就不常用.🍅概念预编译头文件实际上是让你抓取一堆头文件,并将他们转换成编译器可以使用的格式,而不必一遍又一遍地读取这些头文件🍅优势之处它的出现是为了解决一个项目中同一个头文件被反复编译的问题。比如在多个cpp文件中都会包括#include <vector>,那么在编译的时候就会将头文件上的东西复制粘贴到对应的cpp文件。而如果把#include &l原创 2022-05-05 16:01:33 · 628 阅读 · 0 评论 -
虚析构函数 in C++【C++学习笔记】
68.虚析构函数 in C++虚函数 + 析构函数 = 虚析构函数虚析构函数非常非常重要,对于处理多态💡标记为virtual,意味着C++知道可能会有一个方法,一个层次结构下的某种重写的方法。因为在普通的方法面前标记为virtual,那么他就可以被覆写💡💡💡而析构函数有点不一样,虚析构函数的以上是:不是覆写析构函数,而是在原有的基础上加上一个析构函数,其意义就是:这个类可能会被拓展为子类,可能还有一个析构函数也需要被调用直接进入例子开门见山看如何操作class Base {public:原创 2022-04-27 20:13:29 · 412 阅读 · 0 评论 -
联合体(union) in C++【C++学习笔记】
67.联合体(union) in C++联合体有点像类类型,或者结构体类型,只不过它一次只能占用一个成员的内存比如结构体中有四个成员,每一个成员都有着占着不同的字节。而一个联合体只能有一个成员,也就是说如果声明了四个浮点数abcd,他们共用一个内存空间,即4个字节而人们用联合体来做的事情,是和类型双关紧密相关的在你想给同一个变量取两个不同的名字时,它真的很有用(引用:???),当然,可读性上是一定比引用要好的比如有一个正常的abc,有一个坐标轴上的xyz,我想让abc和xyz一一对应,则可以原创 2022-04-27 19:37:04 · 1515 阅读 · 0 评论 -
排序(std::sort) in C++【C++学习笔记】
65.排序(std::sort) in C++std::sort没有任何返回值,排序的时间复杂度是N * logN,这已经算很不错了🍅使用用前需要包括头文件#include <algorithm>默认是从小到大排序💡💡💡sort(初, 末, 谓词(规则))。这里谈谈第三个参数:💡💡💡//如果我们传入的第一个参数排在前面,则返回truebool cmp (int a, int b) { return true; //把a排在前面}bool cmp1 (int a原创 2022-04-27 18:28:52 · 1503 阅读 · 0 评论 -
多维数组的优化 in C++【C++学习笔记】
64.多维数组 in C++数组就是内存块,处理内存最简单的方法是使用指针二维数组的实质:数组的数组三维数组的实质:数组的数组的数组以此类推放堆上的二维数组的创建int main() { //创建一个指向指针合集的指针 int **array = new int*[5]; //但到这一步,储存的实际数组其实还没有被分配 for (int i = 0; i < 5; i < 5; ++i) { arrray[i] = new int[5];原创 2022-04-27 18:08:25 · 1688 阅读 · 1 评论 -
如何不利用OS库去计时 in C++【C++学习笔记】
63.计时 in C++知道程序的运行时间,或者在某一阶段暂停程序运行一段时间,这种控制时间的操作在C++11中的chrono库可以实现(它是C++库的一部分)如果想要了解更多chrono库,可以去cppreference中查询但在有chrono之前,如果想要一个精确的计时器,那么则需要使用操作系统库(例如在windows中,有一个叫QueryPerformanceCounter的东西)计时的内容非常重要。在后面开始集成更多复杂的特性时,开始讨论如何正确的做事,如果编写性能良好的代码时,需要用到原创 2022-04-23 11:28:27 · 177 阅读 · 0 评论 -
多线程 in C++【C++学习笔记】
62.线程 in C++ 如何进行并行化,如何让事情同时发生。如果正常看,平时运行代码的时候都是单线程的,即只让计算机一次只做一行或者一条指令。这对于轻量的代码来说无足轻重,但是如果是繁重的代码,就会需要设备很长时间来计算,故有时将某些工作移到两个不同的执行线程,这是很有益的。🍅操作线程首先要把加入头文件**#include <thread>**(thread即为线程的意思)创建一个线程对象:std::thread 对象名字 (一个函数指针以及其他可选的任何参数)等待一个线程完原创 2022-04-23 10:30:27 · 243 阅读 · 0 评论 -
命名空间 in C++【C++学习笔记】
61.命名空间 in C++#include <iostream>#include <string>#include <algorithm>//一个print是正常打印textvoid print(const char *text) { std::cout << text << std::endl;}//一个print是反转text后再打印void print(const char *text) { std::str原创 2022-04-22 21:18:25 · 833 阅读 · 1 评论 -
为什么不使用using namespace std in C++【C++学习笔记】
60.为什么不使用using namespace std in C++🍅1.不容易分辨各类函数的来源比如我在一个自己的库里定义了一个vector,而标准库里又有一个vector,那么如果用了using namespace std 后,所用的vector到底是哪里的vector呢?std::vector<int>vec1; //goodDiyClass::vector<int>vec2 //goodusing namespace std;using namespace D原创 2022-04-22 17:15:55 · 1226 阅读 · 0 评论 -
lambda in C++【C++学习笔记】
59.lambda in C++lambda本质上是我们定义的一种叫做匿名函数的方式。我们可以用这种方式简易的创建一个函数,而不需要真的实际创建一个函数,就像一个快速的一次性函数lambda更像是一种变量,在实际编译的代码中作为一个符号存在,而不是像正式的函数那样。🍅lambda用法只要你有一个函数指针,你都可以在C++中使用lambda,这就是它的工作原理故lambda的用法是:在设置函数指针指向函数的任何地方,我们都可以将他设置未lambda[]( {参数表} ){ 函数体 }void原创 2022-04-20 20:32:58 · 544 阅读 · 0 评论 -
C语言中的函数指针 【C++学习笔记】
58.函数指针 in C准确来说,接下来的内容讲的是原始风格的函数指针,来自于C语言🍅函数指针的使用💡热知识:正常调用函数是Function(),而如果不带括号如Funcion,则返回的值就是这个指向这个函数的指针void Print() { std::cout << "hello" << std::endl;}int main() { auto a = Print(); //❌,auto无法识别void类型 auto b = Print; /原创 2022-04-20 19:31:39 · 349 阅读 · 0 评论 -
静态数组std array in C++【C++学习笔记】
57.静态数组std array in C++std array是一个实际的标准数组类,是C++标准模板库的一部分array是用来处理静态数组的,这里的静态的意思是不增长的数组,当创建array时就要初始化其大小,并且不能将他容量随后变大变小🍅array用法使用静态数组要包含头文件#include <array>array接受两个模板参数(也可以只选一个类型参数,但99.99%的情况都是两个参数)💡array<类型, 大小> 名字#include <array原创 2022-04-20 18:38:28 · 887 阅读 · 0 评论 -
宏 in C++【C++学习笔记】
55.宏 in C++当编译C++代码时,首先预处理器会过一遍C++所有的以#符号开头(这是预编译指令符号)的语句,当预编译器将这些代码评估完后给到编译器去进行实际的编译。这就是预处理阶段,一个文本编辑阶段💡💡💡宏和模板的区别:它们的发生时间不同,宏是在预处理阶段就被评估了,而模板会被评估的更晚一点用宏的目的:写一些宏将代码中的文本替换为其他东西(纯文本替换)(不一定是简单的替换,是可以自定义调用宏的方式的)#defind WAIT std::cin.get()//这里可以不用放分号,如果放分原创 2022-04-19 22:42:54 · 294 阅读 · 0 评论 -
堆和栈内存的比较 in C++【C++学习笔记】
54堆和栈内存的比较 in C++当我们的程序开始的时候,程序被分成了一堆不同的内存区域,除了堆和栈以外,还有很多东西,但我们最关心这两个🍅论栈和堆的琐事栈通常是一个预定义大小的内存区域,通常约为2兆字节左右堆也是一个预定义了默认值的区域,但是它可以生长,并随着应用程序的进行而改变重要的是,这两个内存区域的实际位置(物理位置)在ram中是完全一样的!(并不是一个存在CPU缓存而另一个存在其他地方)在程序中,内存是用来实际储存数据的。我们需要一个地方来储存允许程序所需要的数据(比如局部变量o原创 2022-04-16 22:04:31 · 544 阅读 · 0 评论 -
C++中的模板的使用(templates)【C++学习笔记】
53 C++中的模板(templates)什么是模板:模板允许你定义一个可以根据你的用途进行编译的模板(有意义下)。故所谓模板,就是让编译器基于DIY的规则去为你写代码🍅函数的模板(对形参)void Print(int temp) { cout << temp;}void Print(string temp) { cout << temp;}void Print(double temp) { cout << temp;}int m原创 2022-04-16 21:06:48 · 1063 阅读 · 0 评论 -
C++中如何处理多返回值【C++学习笔记】
52 C++中如何处理多返回值如何在在一个函数中有多个返回值呢?🍅C++提供的处理方式一void ChangeVal (string &result1, string &result2) { result1 = ""; result2 = "";}把函数定义成void,然后通过参数引用传递的形式“返回”两个字符串,这个实际上是修改了目标值,而不是返回值,但某种意义上它确实是返回了两个字符串,而且没有复制操作,技术上可以说是很好的。但这样做会使得函数的形参太多了,可原创 2022-04-15 21:38:53 · 1143 阅读 · 0 评论 -
C++中创建与使用库(VisualStudio多项目)【C++学习笔记】
51 C++中创建与使用库(VisualStudio多项目)主题:如何在VisualStudio中建立多个项目,以及如何创建一个库让所有项目都能使用🍅创建一个项目作为库的项目(特别是静态库),然后把它链接到一个可执行文件中在一个已有的解决方案上可以add多个new project然后开始设置这两个项目的属性,比如有两个项目分别是game, engine,game为主的项目,engine为DIY的静态库在game项目属性页面下(对项目右键),在general属性下,在Configuration T原创 2022-04-15 20:45:50 · 848 阅读 · 0 评论 -
C++中使用动态库【C++学习笔记】
50 C++中使用动态库动态链接和静态链接的区别:动态链接是在链接时发生的;静态链接是在编译时发生的当编译一个静态库的时候,将其链接到可执行文件,也就是应用程序,或者链接到一个动态库静态链接允许更多的优化发生,因为编译器和链接器,可以从静态链接中看到更多的东西而动态链接只有在真正启动你的可执行文件时,你的动态链接库才会被加载。所以动态库实际上不是可执行文件的一部分,当启动一个可执行文件时,可执行文件会被加载到内存中,与此同时会动态的链接外部的二进制文件(动态库)。即是将一个额外的文件加载到内存中原创 2022-04-15 19:42:35 · 1808 阅读 · 0 评论 -
C++中使用库(静态链接)【C++学习笔记】
49 C++中使用库(静态链接)主要主题:如何在我们的项目中使用外部库如下是以二进制文件的形式进行链接(GLFW库),而不是获取实际依赖库的源代码并自己进行编译🍅下载二进制文件下载32-bit还是下载64-bit的文件,和实际的操作系统没有任何关系,只和你的目标应用程序有关如果要编译的程序是作为X86也就是win32程序,那么就要32位的二进制文件如果在编译一个64位应用程序,那我就要64位的二进制文件一定要把它们匹配起来!不然它们就无法进行链接🍅库的结构库通常包含有两部分:inclu原创 2022-04-15 19:15:07 · 1232 阅读 · 0 评论 -
Vector的优化使用 in C++【C++学习笔记】
48Vector的优化使用 in C++vector能来回变化容量的原理是:新增一个元素,而数组容量不能容纳新元素,那么它就会开辟新的更大的内存块,把原有的和新增的元素全复制过去,然后把旧的内存块删除这种调整大小,重新分配的操作是很费时的(复制所以元素+重新分配),而这是要避免的,而这便是优化的方向,对于复制的优化策略。我们如何避免复制对象呢?特别是基于vector的对象(没有储存vecotr指针,而是对象)🍅寻找策略#include <iostream>#include <v原创 2022-04-13 22:38:31 · 778 阅读 · 0 评论 -
Vector动态数组 in C++【C++学习笔记】
47Vector动态数组 in C++C++的标准库(标准模板库)本质上是一个库,里面装满了容器,容器类型。而之所以被称为标准模板库,因为它可以模板化任何东西。容器包含的数据类型,实际上都由使用者决定,所以东西都由模板组成vector是在std命名空间的,也就是说要std::vector为什么叫vector呢?直接翻译过来就是向量的意思。但其是不应当称为向量,而应当被称为ArrayList,因为他本质上是一个动态数组如何实现数组数量是动态的呢?原理大概是如果元素数量超出了数组大小,则它会重新创建原创 2022-04-11 07:44:26 · 315 阅读 · 0 评论 -
箭头运算符(操作符) in C++【C++学习笔记】
46箭头运算符(操作符) in C++在想调用一个对象里的Print()函数时,可以直接用对象名.Print()但如果是只有指向这个对象的指针呢?如下class Entity{public: void Print() { std::cout << "Hello" << std::endl; }};int main() { Entity e; e.Print(); Entity *ptr = &e;原创 2022-04-11 07:44:39 · 2657 阅读 · 0 评论 -
复制与拷贝构造函数 in C++【C++学习笔记】
45复制与拷贝构造函数 in C++除了引用外,当编写一个变量被赋值给另一个变量的代码时,你总是在复制🍅浅度复制(浅拷贝)class Entity{ int *ptr; Entity(const int &temp) { ptr = new int(temp); } ~Entity() { delete ptr; }};int main(){ int temp = 1; Entity a(temp)原创 2022-04-11 07:44:09 · 175 阅读 · 0 评论 -
智能指针 in c++【C++学习笔记】
44智能指针 in c++智能指针会自动的释放内存,实现自动化用智能指针,当调用new时,而不需要调用delete,而甚至在很多情况下使用智能指针,我们甚至不需要调用new而智能指针本质上是一个原始指针的包装,当创建一个智能指针,它会调用new并为你分配内存,然后这些内存会在某一时刻自动释放🍅最简单的智能指针:unique_ptrunique_ptr是作用域指针,超出作用域时,它就会被销毁,然后调用delete为什么叫unique_ptr呢因为它必须是unique,它必须是唯一的。你不能原创 2022-04-11 07:44:56 · 224 阅读 · 0 评论 -
对象的生存周期 in C++【C++学习笔记】
43对象的生存周期 in c++就是讲内存和对象是怎样在栈上生存的例子:想从一函数中得到一个数组int *CreatArray() { int a[10]; //表面上对了,但是一旦函数一结束,指针a指向的内存空间就被系统释放了 return a;}int main(){ int *b = CreatArray();//实际上这里b指向的内存空间是空的 return 0;}//❌❌❌❌❌❌❌❌❌错了这就是理解对象如何在栈上生存的重要性如果想要从函数原创 2022-04-10 10:20:04 · 297 阅读 · 0 评论 -
40隐式构造函数和隐式转换,还有explicit关键词的确切含义【C++学习笔记】
40隐式构造函数和隐式转换,还有explicit关键词的确切含义隐式的意思是:不会明确地告诉你它要做什么,它有点像在某种情况下自动的工作隐式转换double a = 0.5;int b = a; //这里其实就发生了隐式转换//b = 0隐式构造函数class Entity{ int m_Age = -1; std::string m_Name;public: Entity(const std::string& name, int num) : m_Age(num)原创 2022-04-10 10:18:23 · 189 阅读 · 0 评论 -
怎样创建对象 in C++【C++学习笔记】
怎样创建对象 in C++基本上,当我们编写了一个类并且到了我们实际开始使用该类的时候,就需要实例化它创建对象有两种方法:栈 和 堆(区别是内存来自哪里,我们的对象实际上会创建在哪里)应用程序会把内存分为两个主要部分:堆和栈我们在C++中可以选择对象在哪里创建,是在堆上还是在栈上,它们有不同的功能性差异栈对象有一个自动的生存周期(他们的生存周期是由它声明的地方的作用域决定的,一旦超出作用域,它的内存就会被释放掉。因为作用域结束时,栈就会弹出,在这个栈上,这个作用域的所有东西都会被释放)原创 2022-04-10 10:17:45 · 455 阅读 · 0 评论