C vs C 之一 委託 vs 函式指標

2021-08-11 20:21:55 字數 1666 閱讀 3593

我們常見到c#技術文獻用「類似c/c++函式指標的東西」介紹委託。這樣好像是有道理的,因為二者的確有深層次的相通之處。委託和函式指標都描述了方法/函式的簽名,並通過統一的介面呼叫不同的實現。但二者又有明顯的區別,簡單說來,委託物件是真正的物件,而函式指標變數只是函式的入口位址。對於高層應用來講,委託

的靈活性和適用範圍

更勝函式指標;但對於底層應用,函式指標則是不可替代的。下面分別是委託型別和函式指標型別定義的例子:

delegate int fn(int a, int b) //c#委託

typedef int (*fn)(int a, int b) //c++函式指標

從形式上看,二者的引數列表和返回值都是相同的,只是乙個採用關鍵字delegate,乙個採用指標符號*。似乎「相似」的說法更有把握了,但如果馬上給二者劃等號就操之過急了。我們先實際驗證一下,看看到底有什麼不同:

//c#

delegate int fn(int a, int b) ;

class adder

public adder(int c)

}class multiplier

public multiplier(int c)

}adder adder = new adder(1);

multiplier multiplier = new multiplier(2);

fn fn = adder.add;

fn(1, 2); //結果為4

fn = multiplier.multiple;

fn(2, 3); //結果為12

從上面的**說明了兩個問題:

1.委託物件可以指向不同類的方法,只要符合委託簽名;

2.委託物件是有狀態的(儲存在指向的物件中),委託的行為不僅受到輸入引數的影響,還受到目標物件狀態的影響。

//c++

typedef int(*fn)(int a, int b); 

int add(int a, int b) ;

int multiple(int a, int b) ;

class adder

int add(int a, int b)

private:

int c;

}; typedef int(adder::* fm)(int a, int b);

int _tmain(int argc, _tchar* argv)

c#中的委託是一種支援()操作符的特殊物件。這和c/c++的函式指標是有本質區別的,因為c/c++的函式指標變數並不具有物件性質,它只是單純的函式入口位址。上面的fn只能指向add和multiple兩個普通函式,無法指向adder類的add方法。因為adder類的add方法的簽名並非int(*)(int a, int b),編譯器會自動加上乙個隱式的this指標引數,所以它的簽名是類似int(*)(adder *const this, int a, int b) 的。如果需要指向成員函式的指標,需要用typedef int(adder::* fm)(int a, int b)這樣的形式加上型別限定符。 所以,c++的函式指標不能像c#委託一樣指向不同類的方法;不具有物件的狀態性質;在使用上函式指標也不如委託靈活。所以,當聽到「委託就是類似c/c++函式指標」的說法的時候應該既理解其相似之處,又明了其差別。

C vs C 之一 委託 vs 函式指標

委託與函式指標辨析 我們常見到c 技術文獻用 類似c c 函式指標的東西 介紹委託。這樣好像是有道理的,因為二者的確有深層次的相通之處。委託和函式指標都描述了方法 函式的簽名,並通過統一的介面呼叫不同的實現。但二者又有明顯的區別,簡單說來,委託物件是真正的物件,而函式指標變數只是函式的入口位址。對於...

函式指標VS指標函式 陣列指標VS指標陣列

定義乙個函式 void fuc1 int a 宣告函式指標 int fucptr int 函式指標fucptr指向函式fuc1 fucptr fuc1 呼叫函式指標 fucptr 10 int array1 10 定義乙個陣列 int arrayptr 10 定義乙個陣列指標 arrayptr ar...

C 委託 C函式指標

c 高階程式設計 裡說 net已委託的形式實現了函式指標的概念 這裡簡單比較一下兩者的區別 1 首先看看c下的 函式指標 如何宣告和定義乙個函式變數 typedef int func int x,int y 宣告 func func 定義乙個 函式變數 當已經有這樣乙個實現的函式時 int some...