函數指針,顧名思義,就是指向函數的指針。那么如何聲明一個函數指針呢:答案是返回值以及形參列表與原函數相同,再加個指針符號' * '就好了。
bool lengthCompare(const string &, const string &); //原函數 bool (*pf)(const string &, const string &); //指向函數lengthCompare的指針,未初始化
如上所示。並且很容易知道,當我們把函數名作為一個右值使用時,此函數名會自動地轉化為指針,當然,也可用取地址符(兩者是等價的):
pf = lengthCompare;
pf = &lengthCompare;
既然是等價的,那么自然而然就可以直接使用此指針函數(初始化后)直接調用該函數(而不用解引用):
bool b1 = pf("hello", "goodbye"); bool b2 = (*pf)("hello", "goodbye"); bool b3 = lenthCompare("hello", "goodbye"); //以上三個調用等價(pf由lengthCompare初始化)
那么函數指針的出現有什么用呢?其中一個常見的用處就是用於重載函數的選擇:當我們使用重載函數的時候,一般需要給定形參列表才能讓編譯器找到對應的函數,(未給定形參列表)而如果定義了指向重載函數的指針,就可以通過指針類型來決定使用哪個函數。(下面例子是Qt 的信號槽):
QObject::connect(spinBox, &QSpinBox::valueChanged, silder, &QSlider::setValue); /* 此時會報錯,因為QSpinBox有兩個同名函數信號: void valueChanged(int); void valueChanged(const QString &); */ //解決這個問題的方法就是定義一個指向重載函數的指針 void (QSpinBox::*spinBoxSignal)(int) = &QSpinBox::valueChanged; //第一個重載 //此時調用connect, 將valueChanged變成spinBoxSignal即可
另外,還有函數指針形參和返回指向函數的指針等知識點(可用typedef簡化),這里暫時不贅述(還沒怎么用過)
參考:C++Primer 5th 6.7函數指針