我們都知道,程序=數據結構+算法,
在沒有C++語言的年代,沒有面向對象、模板的語法支持,struct中還不能定義函數,用C語言想要對業務功能(算法,此處即指函數)進行抽象,不想依賴具體的數據結構/數據類型,此時就必須用指向函數的指針來實現抽象與具體的分離(該函數的入參可以是void*,這樣調用者就可以傳入任意類型的參數了)。后來有了C++,就用類成員函數和泛型(模板+functor)來代替了,這樣做有更強的靜態類型檢查機制和編程約束,有利於減少濫用風險。
(函數指針的一個典型應用場合是實現回調。為什么要回調?就是因為此時還不知道具體函數定義,事件發生時才調用、才確定;類比於面向對象中的“多態”+設計模式中的“觀察者模式”,回調的實質仍然是抽象)
那為什么C++中還有類的成員函數指針?因為C與C++中間還有個版本,C with Class(1980's),此時還沒把模板吸收進來,想實現成員函數級抽象還得靠函數指針。后來C++標准出來了,為了兼容老代碼,況且在某些場合下使用起來還是比較靈活、輕量級的(雖然語法比較丑陋),成員函數指針就被保留下來了。
綜上,C語言的函數指針有兩層含義:
1. 意味着這是對一個類的操作,其實就是成員函數。(對於全局的成員函數,給它腦補一個虛擬的“全局類”就好了)
2. 意味着該成員函數對數據類型信息不做明確規定,它只是個處理引擎,具體的數據類型由調用者在使用的時候確定
二者有其一的場合,就可以用函數指針。