C++指向函數的指針定義方式為:
返回類型 (*指針名)(函數參數列表),例如 void (*p)(int)是指向一個返回值為void 參數為int類型的函數。
而若想定義一個指向類成員函數的函數指針該怎么定義呢?對成員函數指針的使用。
(1)非靜態成員函數
定義方式:返回類型 (類名::*指針名)(函數參數列表)例如void (A::*p)(int)是一個指向A類中成員函數的函數指針。
賦值方式:p=&A::函數名,而一般的函數指針的賦值是p=函數名即可,注意區別。(成員函數必須是public類型的)
調用方式:成員函數指針的調用必須通過類對象進行調用,a.*p(int)即可調用成員函數(該成員函數是public類型的)
(2)靜態成員函數
對於靜態成員函數的定義和使用方法都與普通函數指針的相同,只是在賦值的時候和非靜態成員們函數指針的賦值方法相同。
因為靜態成員函數的指針類型是與普通函數指針類型相同的。
----------------------------------------------------------------------------------------------------------------------
對於單類型的成員函數指針的使用就是上述的內容,但是對於C++來說,繼承是其三大特性之一,那么對於繼承類來說,成員函數指針怎么實現動態呢?
(1)賦值問題
與正常的派生類指針或引用可以賦於基類指針或引用不同,基類成員函數可以賦於派生類成員函數指針(任何情況下都不會出錯),反之派生類成員函數在未覆蓋基類函數名的情況下也能賦於基類成員函數指針。如下例:
class A class B class C:public A,B
{ { {
public: public: public:
void printA(int) virtual void printB(int) void printB(int)
{ { {
} } }
}; }; };
void (A::*Pa)(int);void (B::*Pb)(int);void (C::*Pc)(int)
pa=&C::printA;(正確)相當於將C中A類對象的函數傳給指針。
pb=&C::printB;(錯誤)因為printB已經在C類中修改,兩者的類型不同
pc=&A::printA;(正確)
pc=&B::printB;(正確)
總結:只要不被派生類覆蓋的函數均可以賦給基類成員函數指針。
(2)多態調用
接上例:
pb=&B::printB;
(b.*pb)(i);(調用b類中的printB)
(c.*pb)(i);(調用c類中的printB)
但是對於pc指針只能由c類對象調用,不能由基類調用。
根據對象實例的類型去判斷應該調用的函數。