C语言中void*作为形参的用法
最近在实操一本算法书上的代码的时候,碰到了形如int (* comp)(void*,void*)这样的形参列表。
LinkedList *createList(unsigned long size,int(*comp)(void*,void*));
在这里面函数指针的形参列表是void*的,在使用这个createList函数时需要传入一个函数指针,就像这样。
LinkedList* L = createList(sizeof(int), intGreater);
注意,这个intGreater函数的实现是这样的。
int intGreater(int*x, int*y){
return (*x)-(*y);
}
这里的形参列表是(int*,int*),这在C语言的编译器中是可以通过编译的,这就是void*的泛型用法,多牛批的功能啊!
然而,在C++中是无法通过编译的!
C++中void*作为形参的用法
我们现在设计这样两个函数
#include <iostream>
using namespace std;
int intGreater(int* a, int* b)//比较a,b的大小
{
return(*a) - (*b);
}
int compare(void* a, void* b, int(*comp)(void* a, void* b))//接受a,b的地址和一个比较函数的指针
{
return comp(a, b);//用comp所指的函数对a,b所指对象进行比较
}
int main()
{
int a = 2;
int b = 1;
cout << compare(&a, &b,intGreater) << endl;//用intGreater进行比较
}
此时发现编辑器开始报错!
对于这个原因,我查阅了大量技术贴,看了各种关于void* 的描述,都无济于事,整整折腾一个上午。
后来看见一篇讲解关于C++新特性的讲解,其中有说到C++的类型安全性问题,void* 无法在C++中执行隐式转换,这时候我感觉突然发现了什么!!!在上面代码中intGreater的形参列表是(int* ,int* ),而 (* comp)处的形参是(void * ,void* ),这样在C的编辑器中是可以通过隐式转换完成泛型算法设计的,但是这在C++中行不通的!!!天呐,多么牛批的功能在C++中竟然用不了了,当然这也是为了安全性考虑。
好吧。。。现在我们对上面的代码进行一些修改,我们将intGreater的形参列表写成跟(* comp)一模一样的形式,然后再在intGreater函数体内进行强制类型转换。
现在,我们来对上面的代码进行一些修改:
#include <iostream>
using namespace std;
int intGreater(void* a, void* b)//修改成void*形式
{
return(*(int*)a) - (*(int*)b);//进行强制类型转换
}
int compare(void* a, void* b, int(*comp)(void* a, void* b))//接受a,b的地址和一个比较函数的指针
{
return comp(a, b);//用comp所指的函数对a,b所指对象进行比较
}
int main()
{
int a = 2;
int b = 1;
cout << compare(&a, &b,intGreater) << endl;//编译通过,YES!!!
}
输出结果:
好了,问题解决!
以后在学习书上代码的时候一定要注意一下作者所使用的语言版本!!!天坑…