没有找到文章
Lecture 1
本节课旨在对 C++ 有一个基本概念。
Baseline
用最简单的排序代码作为 baseline。
Reference
显然,寻找最小值索引和元素交换两个操作被重复使用。最简单的优化是把这两个过程抽取为函数,重复调用即可。
写
swap 函数时与 C 有些不同。通常在 C 中会向函数中传入参数的地址,在交换的时候解引用。在 C++ 中我们有如下更简便的方式:这样的表示方式称为 Reference。
Overloading
我们的 baseline 中把数据类型全部写死为 复制大法。例如:
int,要改成支持 double 的形式,我们可以用C++ 支持传入数据不同(类型不同、名称不同都可以)的同名函数。C++ 编译器在编译时会结合函数名和参数表生成一个真正的函数名,称为 Overloading(函数重载)。
Function Template
还是上一个问题,对于不确定的数据类型,复制大法显然不太合理。Template 可以解决我们的问题。
template<typename T> 相当于将 T 定义为了一个替代明确数据类型的占位符,当函数被调用时自定根据传入的参数生成实际的函数。例如:Note: 在所有函数前都需要加上
template<typename T> 。Operator
更进一步,如果数据类型时是我们自己定义的,情况将有很大变化。例如我们自己定义了
student 结构体:编译时会报错:

编译器不清楚对于自定义的结构体实例要如何互相比较以及如何输出。我们可以通过人为定义算子的方式来解决这个问题。
直接定义在结构体中,作为结构体的 member function(成员函数),例如:
实际上,作为成员函数时,函数会将对象作为隐藏的第一个参数调用,所以可以简洁地写成上面的形式。
作为普通函数定义在结构体外可能更直观:
类似地,我们也可以定义算子
<< :Encapsulation
现在我们让情况更复杂一些: 定义三角形、矩形和圆形三类数据。这次我们改用 给 PyTorch 做铺垫是吧
class 。private 是一种 Encapsulation(封装),表明其中的变量不允许用户直接访问,用户与对象交互的方式应该是“发消息”,实际上就是调用函数。class 与 struct 的区别在于前者中的变量默认是 private ,后者默认是 public 。Constructor
但此时我们没法像对
struct 那样直接对 class 赋值:要对其赋值,我们需要一个 Constructor(构造函数):
可以看到,这个函数只起到结构上的作用,函数内部是空的。赋值语句如下:
Inheritance
现在我们完善这三个类,用 member function 计算它们的面积和周长:
观察这三个类的实现代码,其中有很多共性的东西显然可以提取出来。我们引入父类(我永远喜欢 PyTorch),让
area 和 perimeter 在父类中定义,在子类中被继承,称为 Inheritance 。比如我们定义父类 shape :那么例如
Rectangle 就可以定义为:Note: 不能直接用
shape 创建这三类对象。shape 中的变量是 area 和 perimeter ,Rectangle 中的变量还有 w 和 h ,当使用类似如下语句创建对象时:会发生截断,即对象中只有
area 和 perimeter 两个变量。正确的语句是:此时,
arr 中存的是子类对象的指针;new 相当于创建了一个对应对象的指针,好处是可以“向上造形”,即创建 Rectangle 类的指针赋值给 shape 类的指针是没问题的,但相反过程就会产生截断。Polymophism
到这里,如果我们直接循环去计算面积和周长还是会有问题:
父类中共享的只是数据, 函数还定义在子类中。但我们直接在父类中定义是有一些问题的:
直接这样定义,会导致每次调用该函数都会执行父类中的代码(虽然这里是空的),比较类似 PyTorch 中对父类
nn.Module 继承,调用 __init__() 初始化函数时会将父类中的初始化执行一遍。那么就像我们会重写 forward() 一样,这里也应该是在不同的子类里重写 calc_area() 和 calc_perimeter() 函数。我们称子类中对父类中的函数有不同需求的这种情况为 Polymophism(多态)。vitrual ... = 0 意味着在定义子类时需要重写该函数。override 表示复写(不加也可以 work)。一些额外优化
当我们尝试在输出中加上类的名字:
我们发现编译器会认为
s.name() 有可能改变 s 的状态,这与 const 是冲突的。这时候我们需要人为向编译器承诺 name() 不会改变 s 中的状态:还剩一点,下次再说。
Reference Code
xchen_algorithm.h
main.cpp
Loading...