C++ VS C#(7):指向函数的指针和委托
//=====================================================================
//TITLE:
// C++ VS C#(7):指向函数的指针和委托
//AUTHOR:
// norains
//DATE:
// Thursday 17-January-2011
//Environment:
// Visual Studio 2010
// Visual Studio 2005//Modify
// AM,Thursday 17-January-2011 初稿
// PM,Thursday 17-January-2011 修改C++调用的方式
//=====================================================================1. 指向函数的指针和委托
开篇点题,假设我有两个形参和返回类型都一样的两个函数,如:
view plaincopy to clipboardprint?
static int Multiply(int Param1,int Param2)
{
return Param1 * Param2;
}
static int Divide(int Param1,int Param2)
{
return Param1 / Param2;
}
static int Multiply(int Param1,int Param2)
{
return Param1 * Param2;
}static int Divide(int Param1,int Param2)
{
return Param1 / Param2;
}
现在我不想直接调用这两个函数,而是间接通过某种方式来进行调用。这话看起来似乎有点拗口,不直接,我们还是来换一种说法。假设我们有一个容器,而该容器能够获取函数的相关信息,但我们不必去关心调用函数是什么,只需要调用容器,让容器去选择相应的函数即可。
这个所谓的容器,无论是在C++还是在C#,都是存在的。那么,我们首先从C++开始。
在C++中,这个容器的名字叫做:指向函数的指针。没错,就是指针。指针绝对是C++的精髓,就像万金油一样,放到哪里都是真理。只不过这里的指针是指向函数的,所以声明起来似乎有点怪异,代码如下:
view plaincopy to clipboardprint?
//定义两个变量,在函数调用时使用
int a = 10;
int b = 20;
//声明一个指向函数的指针
int (*pFunc)(int,int);
//将函数地址赋值给指针
if(bDiv != FALSE)
{
pFunc = Divide;
}
else
{
pFunc = Multiply;
}
//调用指向的函数
pFunc(a,b);
//调用也可使用这种形式
(*pFunc)(a,b);
//定义两个变量,在函数调用时使用
int a = 10;
int b = 20;
//声明一个指向函数的指针
int (*pFunc)(int,int);
//将函数地址赋值给指针
if(bDiv != FALSE)
{
pFunc = Divide;
}
else
{
pFunc = Multiply;
}
//调用指向的函数
pFunc(a,b);//调用也可使用这种形式
(*pFunc)(a,b);
赋值好理解,和普通的赋值没什么区别;调用理解上也不算很难,简单点来看也就是相当于Multiply(a,b),复杂一点的加*也可当成是获取指针指向的函数来理解。而声明的这个语句:int (*pFunc)(int,int),怎么咋看咋别扭呢?没办法,这个我们也改变不了,因为标准是定死的。只不过,C++有趣就有趣在这里,你可以使用typedef来使得声明更清晰!不信,我们一起来看:
view plaincopy to clipboardprint?
//定义一个函数指针类型,并且该类型名为Func
typedef int (*Func)(int,int);
//声明一个指向函数的指针
Func pFunc;
//定义一个函数指针类型,并且该类型名为Func
typedef int (*Func)(int,int);
//声明一个指向函数的指针
Func pFunc;
相对之前的直接声明,这样的声明是不是更加清楚?当然,代价就是多出一行typedef代码。
至此,C++的描述就暂时告一段落,我们接下来看看C#。在C#中,是不存在指针的,自然也不会有指向函数的指针这种玩意,取而代之的是委托。委托的声明非常类似于函数,但它不带函数体,并且需要使用delegate关键字。如果以C#来实现,那么代码如下:
view plaincopy to clipboardprint?
//定义一个委托FuncDelegate,其返回类型和形参与Multiply和Divide相同
delegate int FuncDelegate(int Param1, int Param2);
//声明两个变量,用来函数定义用
int a = 10;
int b = 20;
//声明一个委托变量
FuncDelegate Func;
//给委托变量赋值
if (bDiv != false)
{
Func = new FuncDelegate(Divide);
}
else
{
Func = new FuncDelegate(Multiply);
}
//调用对应的函数
Func(a,b);
//定义一个委托FuncDelegate,其返回类型和形参与Multiply和Divide相同
delegate int FuncDelegate(int Param1, int Param2);
//声明两个变量,用来函数定义用
int a = 10;
int b = 20;
//声明一个委托变量
FuncDelegate Func;
//给委托变量赋值
if (bDiv != false)
{
Func = new FuncDelegate(Divide);
}
else
{
Func = new FuncDelegate(Multiply);
}
//调用对应的函数
Func(a,b);
C#中采用委托的方式,其实和C++的typedef非常相像,都是必须先定义一个类型,然后用该类型去声明一个变量。最大的不同在赋值阶段,C++只需要简单的将函数地址赋给指针,而C#必须用new声明一个对象,并且还要求相应的函数作为形参传入。在这个阶段,似乎C#显得更为复杂。到了调用阶段,C++和C#都可以容器后加个括号就能完成调用,但C++还多了一种*的方式。虽然这种方式有点鸡肋,但毕竟多了一种乐趣,何乐而不为呢?
补充:软件开发 , C++ ,