程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++ VS C#(7):指向函數的指針和委托

C++ VS C#(7):指向函數的指針和委托

編輯:C++入門知識

//=====================================================================
//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++還多了一種*的方式。雖然這種方式有點雞肋,但畢竟多了一種樂趣,何樂而不為呢? 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved