指向函数的指针

  函数指针是指指向函数而非指向对象的指针。像其他指针一样,函数指针也指向某个特定的类型。函数类型由其返回类型以及形参表确定,而与函数名无关: 

1 //pf points to function returning bool that takes two const string references 
2 bool (*pf) (const string &, const string &);

  这个语句将pf声明为指向函数的指针,它所指向的函数带有两个const string&类型的形参和bool类型的返回值。

*pf 两侧的圆括号是必需的:
1 // declares a function named pf that returns a bool * 2 bool *pf(const string &,const string &);

1.用typedef简化函数指针的定义

  函数指针类型相当的冗长。使用typedef为指针类型定义同义词,可将函数指针使用大大简化:

1 typedef bool (*cmpFcn) (const string &, const string &);

  该定义表示cmpFcn是一种指向函数的指针类型的名字。该指针类型为“指向返回bool类型并带有两个const string 引用形参的函数的指针”。在要使用这种函数指针类型时,只需直接使用cmpFcn即可,不必每次把整个类型声明全部写出来。

2.指向函数的指针的初始化和赋值

  在引用函数名但又没有调用该函数时,函数名将被自动解释为指向函数的指针。假设有函数:

1 //compares lengths of two strings
2 bool lengthCompare(const stirng &,const string &);

  除了用作函数调用的左操作数以外,对lengthCompare的任何使用都被解释为如下类型的指针: 

1 bool (*)(const string &, const string &);

  可使用函数名对函数指针做初始化或赋值: 

1 cmpFcn pf1 = 0;              //ok:unbound pointer to function
2 cmpFcn pf2 = lengthCompare;  //ok:pointer type matches function's type
3 pf1 = lengthCompare;         //ok:pointer type matches function's type
4 pf2 = pf1;                   //ok:pointer types match

  此时,直接引用函数名等效于在函数名上应用取地址操作符: 

1 cmpFcn pf1 = lengthCompare;
2 comFcn pf2 = &lengthCompare;

函数指针只能通过同类型的函数或函数指针或0值常量表达式进行初始化或赋值。

  将函数指针初始化为0,表示该指针不指向任何函数。

  指向不同函数类型的指针之间不存在转换: 

1 string::size_type sumLength(const string &, const string &);
2 bool cstringCompare(char *, char *);
3 // pointer to function returning bool taking two const string &
4 cmpFcn pf;
5 pf = sumLength;            //error:return type differs
6 pf = cstringCompare;&nbsp  //error:parameter type differ
7 pf = lengthCompare;&nbsp   //ok:function and pointer types match exactly

 3.通过指针调用函数

   指向函数的指针可用于调用它所指向的函数。可以不需要使用解引用操作符,直接通过指针调用函数:

1 cmpFcn pf = lengthCompare;
2 lengthCompare("hi", "bye");       //direct call
3 pf("hi","bye");                   //equivalent call: pf1 implicitly derefenrenced
4 (*pf) ("hi", "bye");              //equivalent call: pf2 implicitly derefenrenced

如果引用指向函数的指针没有初始化,或者具有0值,则该指针不能在函数调用中使用。只有当指针已经初始化,或被赋值为指向某个函数,方能安全地用来调用函数。

4.函数指针形参

  函数的形参可以指向函数的指针。这种形参可以用以下两种形式编写:

1 /* useBigger function's third parameter is a pointer to function that function returns a bool and takes two const string references two ways to specify that parameter: 
2 */
3 // third paramter is a function type and is automatically treated as a pointer to function 
4 void useBigger(const string &, const string &, bool(const string &, const string &) );
5 // equivalent declaration: explicit define the parameter as a pointer to function 
6 void useBigger(const string & ,const string &, bool (*)(const string &, const string &) );

5.返回指向函数的指针

  函数可以返回指向函数的指针,但是,正确写出这种返回类型相当不容易:

1 // ff is a function taking an int and returning a function pointer 
2 // the function pointed to returns an int and takes an int* and an int 
3 int (*ff(int))(int *, int);

 阅读函数指针声明的最佳方法是从声明的名字开始由里而外理解。

  要理解该声明的含义,首先观察:

1 ff(int)

   将ff声明为一个函数,它带有一个int型的形参。该函数返回 int (*)(int *, int);它是一个指向函数的指针,所指向的函数返回int型并带有两个分别是int*类型和int型形参。

   使用typedef可使该定义更简明易懂:

1 // PF is a pointer to a function returning an int, taking an int* and int 
2 typeded int (*PF) (int *, int);
3 PF ff(int);                    //ff returns a pointer to function 

允许将形参定义为函数类型,但函数的返回类型则必须是指向函数的指针,而不能是函数。 

    具有函数类型的形参所对应的实参将被自动转换为指向相应函数类型的指针。但是,当返回的是函数时,同样的转换操作则无法实现:

1 // func is a pointer type,not a pointer to function!
2 typedef int func (int *, int);
3 void f1(func);      //ok:f1 has a parameter of function type
4 func f2(int);       //error:f2 has a return type of function type
5 func *f3(int);      //ok:f3 returns a pointer to function type 

 6.指向重载函数的指针

   C++语言允许使用函数指针指向重载的函数:

1 extern void ff(vector<double>);
2 extern void ff(unsigned int);
3 
4 // which function does pf1 refer to?
5 void (*pf1)(unsigned int) = &ff; //  ff(unsigned)

   指针的类型必须与重载函数的一个版本精确匹配。如果没有精确匹配的函数,则对该指针的初始化或赋值都将导致编译错误:

1 //error: no match: invalid parameter list
2 void (*pf2) (int) = &ff
3 
4 //error: no match: invalid returntype
5 double (*pf3) (vector<double>);
6 pf3 = &ff;

 

 

posted @ 2013-11-19 21:23  海道  阅读(221)  评论(0编辑  收藏  举报