C++通过虚函数来实现多态,而C语言则可以通过函数指针来实现多态。
记录一些自己对于函数指针和虚函数的理解
定义:每一个函数都占用一段内存单元,它们有一个起始地址,指向函数入口地址的指针称为函数指针。
语法说明
指向函数的指针变量的一般定义形式为:数据类型 (*指针变量名) (参数表);
首先需要对以下两种表示形式进行区分
函数指针的定义形式中的数据类型是指函数的返回值的类型。
int (*p)(int a, int b); //p是一个指向函数的指针变量,所指函数的返回值类型为整型
int *p(int a, int b); //p是函数名,此函数的返回值类型为整型指针
指向函数的指针变量不是固定指向哪一个函数的,而只是表示定义了一个这样类型的变量,它是专门用来存放函数的入口地址的;在程序中把哪一个函数的地址赋给它,它就指向哪一个函数。
就是说我们可以声明函数指针,这样在接下来的调用中,可以通过将指针指向我们想要调用的函数来调用该函数。举例如下
int Func(int x); /*声明一个函数*/
int (*p) (int x); /*定义一个函数指针*/
p = Func; /*将Func函数的首地址赋给指针变量p*/
那么函数指针这样做的好处是什么呢:笼统的来讲是可以实现
1.实现面向对象编程中的多态性。2.回调函数。
可能上面的话对于像我这样的初学者来说还是不能够体会其真正含义,借用别人说过的例子来说,就是你有了一只手,可以用来装备并切换武器打怪,比如可以装备刀子,或者装备棍子。当你的武器只有一种或者比较少的时候,可能这只手切换武器的功能不常用到。当到了后期,你的武器多了,那你因为有了这只能装备并切换武器的手,而可以更有效率的打怪。那么你的这只手就可以看作一个函数指针。
当需要实现较为大的工程时,函数指针的作用也会愈发的凸显出来。
(1)指向普通函数的指针
int int_add(int a, int b)
{
return (a+b);
}
int int_sub(int a, int b)
{
return (a-b);
}
int (*int_operator)(int, int) = int_add;
int _tmain(int argc, _TCHAR* argv[])
{
cout<<int_operator(4, 5)<<endl; // output 9
int_operator = int_sub;
cout<<int_operator(4, 5)<<endl; // output -1
return 0;
}
int_operator会被编译器解释成类型int(*)(int, int)的一个指针。
调用方式还可以写作:(*int_operator)(4, 5),这样的好处是让人一眼就能看到int_operator是一个函数指针。
函数指针和指向函数的返回值的类型和参数都必须严格一致;
(2)函数指针数组
int (*pFuncArray[10])();
表示定义了一个数组,该数组中的每一个元素表示一个函数指针。
(3)指向函数数组的指针
int cmp_len(const char *str1, const char *str2)
{return ((int)strlen(str1) - (int)strlen(str2));}
int cmp_str(const char *str1, const char *str2)
{return strcmp(str1, str2);}
typedef int(*PCMP_FUNC)(const char*, const char*);
PCMP_FUNC pCmpFuncs[2] =
{
cmp_len,
cmp_str,
};
// 声明指向pCmpFuncs的指针
PCMP_FUNC (*ppCmps)[2] = &pCmpFuncs;
(*ppCmps):表明ppCmps是一个指针;
(*ppCmps)[2]:后面紧跟[2],表明ppCmps是一个指向‘两个元素数组’的指针
PCMP_FUNC表明了该数组元素的类型,它是指向函数的指针,返回值为int,有两个const char*类型的参数;
对于虚函数多态等方面还未能深入体会。
在此对于虚函数和函数指针的不同以及理解先占个坑,等进一步学习体会以后再来补充。