在用
C++
编写程序时,经常需要在一个函数中调用其他函数,如果希望在一个函数中根据不同的参数调用不同的函数(这些函数的返回值和参数值都相同),此时就会考虑到使用函数指针。使用函数指针可以使得您的代码更加精练。
1、普通函数指针的使用:
首先让我们来看下面的一个例子:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
bool IsRed( string color ) {
return ( color == "red" );
}
bool IsGreen( string color ) {
return ( color == "green" );
}
bool IsBlue( string color ) {
return ( color == "blue" );
}
void DoSomethingAboutRed() {
cout << "The complementary color of red is cyan!/n";
}
void DoSomethingAboutGreen() {
cout << "The complementary color of green is magenta!/n";
}
void DoSomethingAboutBlue() {
cout << "The complementary color of blue is yellow!/n";
}
void DoSomethingA( string color ) {
for ( int i = 0; i < 5; ++i )
{
if ( IsRed( color ) ) {
DoSomethingAboutRed();
}
else if ( IsGreen( color ) ) {
DoSomethingAboutGreen();
}
else if ( IsBlue( color) ) {
DoSomethingAboutBlue();
}
else return;????????
}
}
void DoSomethingB( string color ) {
if ( IsRed( color ) ) {
for ( int i = 0; i < 5; ++i ) {
DoSomethingAboutRed();
}
}
else if ( IsGreen( color ) ) {
for ( int i = 0; i < 5; ++i ) {
DoSomethingAboutGreen();
}
}
else if ( IsBlue( color) ) {
for ( int i = 0; i < 5; ++i ) {
DoSomethingAboutBlue();
}
}
else return;
}
// 使用函数指针作为参数,默认参数为&IsBlue
void DoSomethingC( void (*DoSomethingAboutColor)() = &DoSomethingAboutBlue ) {
for ( int i = 0; i < 5; ++i )
{
DoSomethingAboutColor();
}
}
void DoSomethingD( string color ) {
// define function point
// (定义函数指针,需要与DoSomethingAbout***的返回值和参数一致)
void (*DoSomethingAboutColor)();
// 根据不同的color参数为函数指针赋值
if ( IsRed( color ) ) {
DoSomethingAboutColor = &DoSomethingAboutRed; //记住这里需要用&符号
}
else if ( IsGreen( color ) ) {
DoSomethingAboutColor = &DoSomethingAboutGreen; //记住这里需要用&符号
}
else if ( IsBlue( color) ) {
DoSomethingAboutColor = &DoSomethingAboutBlue; //记住这里需要用&符号
}
else return;
for ( int i = 0; i < 5; ++i )
{
DoSomethingAboutColor();
}
}
int main( int argc,char* argv[] ) {
cout << "DoSomethingA:/n" ;
DoSomethingA( "red" );
cout << endl;
// 使用默认函数指针&DoSomethingAboutBlue
cout << "DoSomethingC with default parameter:/n" ;
DoSomethingC();
cout << endl;
cout << "DoSomethingC with &DoSomethingAboutRed:/n" ;
DoSomethingC( &DoSomethingAboutRed );
cout << endl;
cout << "DoSomethingD:/n" ;
DoSomethingD( "red" );
cout << endl;
return 0;
}
可以看到在DoSomethingA函数中,每次循环都需要判断一次color的值,这些属于重复判断;在DoSomethingB函数中,for 循环重复写了三次,代码不够精练。如果我们在这里使用函数指针,就可以只判断一次color的值,并且for 循环也只写一次,DoSomethingC给出了使用函数指针作为函数参数的代码,而DoSomethingD给出了使用string作为函数参数的代码。
2、类成员函数指针的使用
对于类的成员函数,其函数指针的定义和使用方法与上面普通函数指针还有一些差别,定义时需要在函数名之前加入类的界定符以指明该函数指针调用的函数是属于哪一个类,在调用的使用也需要在调用名称前添加(this->*)。下面举一个使用类成员函数指针的例子。
#include <string>
#include <iostream>
using namespace std;
class Color {
public:
Color( string clr ) : m_color( clr ) {
}
Color( const Color &src ) : m_color( src.m_color ) {
}
Color& operator=( const Color &src ) {
if ( this != &src ) {
m_color = src.m_color;
}
return *this;
}
~Color() {
}
bool IsRed() {
return ( m_color == "red" );
}
bool IsGreen() {
return ( m_color == "green" );
}
bool IsBlue() {
return ( m_color == "blue" );
}
void DoSomethingAboutRed() {
cout << "The complementary color of red is cyan!/n";
}
void DoSomethingAboutGreen() {
cout << "The complementary color of green is magenta!/n";
}
void DoSomethingAboutBlue() {
cout << "The complementary color of blue is yellow!/n";
}
void DoSomethingD() {
// define function point
// (定义函数指针,需要与DoSomethingAbout***的返回值和参数一致)
void (Color::*DoSomethingAboutColor)();
// 根据不同的color参数为函数指针赋值
if ( IsRed() ) {
DoSomethingAboutColor = &Color::DoSomethingAboutRed; //记住这里需要用&符号
}
else if ( IsGreen() ) {
DoSomethingAboutColor = &Color::DoSomethingAboutGreen; //记住这里需要用&符号
}
else if ( IsBlue() ) {
DoSomethingAboutColor = &Color::DoSomethingAboutBlue; //记住这里需要用&符号
}
else return;
for ( int i = 0; i < 5; ++i )
{
// 这里调用时需要使用this->*,并且需要加上括号
(this->*DoSomethingAboutColor)();
}
}
private:
string m_color;
};
int main( int argc,char* argv[] ) {
cout << "DoSomethingD of class Color:/n" ;
Color clr( "blue" );
clr.DoSomethingD();
return 0;
}