c++函数重载,模板,指针
Kong Liangqian Lv6

函数重载

可以针对不同的参数列表定义多个同名的函数,如果只是函数名不同是不可以被重载的

1
2
3
4
5
6
7
8
9
int sum (int, int) {
...
};
double sum(double, double) {
...
};
float sum(float, float) {
...
};

函数模板

函数重载对于使用者来说记忆负担的确是减轻了,但是针对开发者来说,还是复杂了一些,因此模板应运而生!

1
2
3
4
5
template <typename T>
T sum(T x, T y) {
cout << typeid(T).name();
return x + y;
}

定义的只是一个模板,他并不知道运行的时候到底是哪个具体的类型,因此我们需要实例化

显式的实例化

下面三种实例化方式都可以

1
2
3
template double sum<double>(double, double);
template double sum<>(double, double);
template double sum(double, double);

隐式实例化

在显式实例化没有找到的时候,他会去找调用,譬如

1
2
3
4
// 这里会隐式实例化为 sum<int>(int, int)
cout << sum<int>(2.2f, 3.0f) << endl;
// 这里会隐式实例化为 sum<float>(float, float)
cout << sum(2.2f, 3.0f);

T 为其他类型

我们定义了

1
2
template <typename T>
T sum(T x, T y);

如果这个时候T 为一个结构体Point,sum里面的加法就需要进行两个结构体的加法,如果没有定义结构体的加法,则会报错

我们还可以显示实例化,专门为一个结构体开一个特例,称为特例化,特例化需要在template后面加上<>

1
2
3
4
5
6
7
8
template<>
Point sum(Point p1, Point p2)
{
Point pt;
pt.x = p1.x + p2.x;
pt.y = p1.y + p2.y;
return pt;
}

函数指针

一个指向函数的指针,而不是指向内存数据中的指针。有了函数指针,我们可以和Python一样,把一个函数名给一个变量了。

定义一个函数指针

1
float (*pointer) (float a, float b);

相比于定义正常的一个指针,后面多了一个参数列表,表示该函数指针只能指向后面这样的参数列表的函数,譬如

1
2
3
float norm_l1(float x, float y) {
...
}

给函数指针赋值

1
2
pointer = &norm_l1;
pointer = norm_l1; // 这两种方式是等价的

调用

1
2
3
pointer(3.0f, 4.0f);
// 或者
(*pointer)(3.0f, 4.0f);

函数指针的作用

把函数当做一个参数,传递到其他函数里面,作为回调函数

假设我们需要做一个排序算法,但是排序的对象不确定,因此排序的标准也不同,比如Struct person排序,Point排序等等,此时我们可以把排序标准留给别人定义,然后作为回调传入函数

1
void qsort(int count, int(*comp)(const void*, const void*));

函数引用

和函数指针差不多,注意声明的时候必须初始化

1
float (&pointer) (float a, float b) = norm_l1;
 Comments