【笔记】Cherno C++ Tutorial note 03

Templates模板

模板就像一个蓝图

1
2
3
4
5
6
7
8
9
10
11
void Print(int value) {
std::cout<<value<<std::endl;
}
void Print(std::string value) {
std::cout<<value<<std::endl;
}
int main() {
print(5)
print("Hellow")
print(5.0f)
}

这种不断重复重载的函数可以用一个函数包裹,

1
2
3
4
5
6
7
8
9
10
11
12
template<typename T>

void Print(T value) {
std::cout<<value<<std::endl;
}//这个函数是一个模板,只有当调用时,它才创建一个对应的函数
//它不参与编译,只有它创建的函数才参与编译
int main() {
print(5)
print<int>(5)
print("Hellow")
print(5.0f)
}

c++的标准模板库STL就是templates

1
2
3
4
5
6
7
8
9
10
11
template<typename T, int N>
class Array {
private:
T m_Array[N];
public:
int GetSize() const {return N;}
};

int main() {
Array<int,5> array;
}

Stack vs Heap Memory堆内存与栈内存

stack和heap地址都是RAM上的两部分区域

stack定好了区域大小 2MegaBytes

heap的大小是动态改变的

区别在于他们如何分配内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
struct Vector3 {
float x,y,z;
Vector3()
: x(10),y(5),z(1) {}
}

int main() {
//stack分配
int value = 5;
int array[5];
array[0] = 1;
array[1] = 2;
array[2] = 3;
array[3] = 4;
array[4] = 5;
Vector3 vector;
//观察内存可以发现,stack所有的分配,都在stack的指针位置进行,分配出多少,stack指针就往后移多少,并返回这个指针
//scope结束,栈内存销毁

//heap分配
int* hvalue = new int;
*hvalue = 5;
int* harray = new int[5];
harray[0] = 1;
harray[1] = 2;
harray[2] = 3;
harray[3] = 4;
harray[4] = 5;
Vector3* hvector = new Vector3();

delete havlue;
delete[] harray;
delete hvector;
//heap分配
//new其实就是调用malloc
//当malloc分配内存时,会根据所需要的内存大小,在内存上寻找足够的一块大小的位置分配,并提供这个地址的指针
}

使用堆分配可能造成Cache Miss缓存丢失,少数的缓存丢失没有影响

堆栈分配最大的区别就是在分配方式上。

堆分配会更慢。

只有无法在栈上分配,如需要更多的生命周期、更大的数据,再使用堆分配,一般没事最好栈分配,毕竟快很多。

(所以内存碎片大概就是指堆上各个内存之间存在的小间隙?)

Macros宏指令

预处理过程的宏

编译C++时

  • 首先是预处理pass
    • 带#符号的语句
    • 实际是文本编辑阶段,进行文本替换
    • 控制哪些程序语句进入编译器

并不是总是要用宏

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <string>

#define WAIT std::cin.get()//只在当前文档中生效
#define LOG(x) std::cout<< x << std::endl
int main() {
LOG("Hello")
WAIT;// 根据define进行文本替换
}

你可以在项目设置的预处理命令看到一些定义

Debug

image-20220701143548474

Release

image-20220701143602730

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>

#define WAIT std::cin.get()

#ifdef _DEBUG//也可以在预处理命令上赋值,#ifdef _DEBUG == 1,
#define LOG(x) std::cout<< x << std::endl
#else//也有elif
#define LOG(x)
#endif

#define MAIN int main() \//反斜杠可以在宏命令中换行
{\
std::cin.get();\
}
//这样只有debug模式才会log
int main() {
LOG("Hello")
WAIT;
}

待补充:

auto关键字

Static Arrays(std::array)静态数组

Functions Pointers函数指针

Lambdas

using namespace std

Namespaces命名空间

Threads线程

Timing计时器

Multidimensional Arrays(2D arrays)多维数组

Sorting

Type Punning类型双关