S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

指向函数的指针的一点理解 (转)

Posted on 2009-02-01 21:59 S.l.e!ep.¢% 阅读(307) 评论(0)  编辑 收藏 引用 所属分类: C++

指向函数的指针的一点理解

准确地讲,本文所涉及的内容是C++中较难理解的,本文的目的不是在于将它们解释清楚,因为这需要你循序渐进地做很多练习才可以。看下面一个例子:

				int 
				(*func(
				bool 
				real))(
				int
				, 
				int
				)
		

你觉得它的返回值是什么?

这里就涉及到了如何理解指向函数的指针的问题了。一些来自C++教材的建议是从里向外解读这个表达式,这里所谓的里面就是func(bool real),那么剩下的部分就是所谓的返回值了?有点生硬吧。下面就让我们循序渐进地看看如何理解更好?

为什么会对这个表达式的返回值产生疑问?

要解决问题通常需要找出问题所在,这里是基于这样一种思维定势,那就是我们通常习惯于这样一种声明变量的方式:

int a;

这里我们声明a是一个int类型的变量。而对于返回值,我们通常也是采用类似的方式,如一个返回值为int类型的函数通常可以以下面的方式进行声明:

int func([params]);

因此我们惯性地认为返回值就是最左侧的一个类型名,虽然这通常是对的,但是针对上面的那个例子则显得十分尴尬。

让我们看看一个指向函数的指针的声明式:

				int 
				(*
				pCompare)(
				int
				, 
				int
				);
		

这个指针的名字就是pCompare,令人奇怪的是pCompare并不是在整个声明式的最右边,类型也肯定不是int,而是一个复杂的表达式。让我们用typedef来声明就会发现typedef的使用也不太一样。

				typedef int 
				(*
				PF
				)(
				int
				, 
				int
				);
		

我们发现跟惯用的typedef *** ???;的方式也截然不同,在上面这个typedef过后,整个表达式可以被简化成:

				PF pCompare;
		

现在我们似乎就一见如故了,现在的表达式看起来中规中矩,普通的声明都是类型名加变量名完成声明,而函数指针的声明则是在一个表达式中一个固定的位置进行声明。

 

				int 
				(*
				)(
				int
				, 
				int
				);
		

在上文中划线的部分即为声明的部分,也就是这点不同让我们逐渐迷失了方向。

现在让我们写一个返回指向函数的指针的函数,也就是返回值是PF的函数,这就像我们从返回int类型的变量到返回int类型值的函数一样,因此使用以下方式即可:

PF func([params]);

现在让我们扩展PF,将它还原,也就是把右侧的func([params])部分移到那个横线的位置上。现在我们就可以很轻松地理解本文开头的那个函数,原来是返回值为int (*)(int, int)的函数

				int 
				(*func(
				
						bool 
				
				
						real))(
				int
				, 
				int
				)
		

以上划线的部分也就是一个函数扣除返回值的部分。也就等价于

				PF 
				func(
				bool 
				real)
		

至此你应该能够分析更加复杂的表达式了。

下面的示例旨在帮助理解本文:

/*
 * main.cc
 *
 *  Created on: 2009-2-1
 *      Author: Volnet
 
*/

#include 
< stdlib.h >
#include 
< iostream >
using  std::cout;
using  std::endl;

int  myCompare1(
        
int  a,  int  b,
        
int  ( * Compare)( int int ));
int  realCompare( int  a,  int  b);
int  fakeCompare( int  a,  int  b);

typedef 
int  ( * PF)( int int );
int  myCompare2(
        
int  a,  int  b,
        PF Compare);

PF getAPointerFunc1(
bool  real);
int  ( * getAPointerFunc2( bool  real))( int int );

int  main( void ){
    
int  typeDeclared;
    typeDeclared 
=   1 ;

    
// PF pCompare;
     int  ( * pCompare)( int int );

    
if (pCompare  ==  NULL)
        cout
<< " pCompare == NULL " << endl;
    
else
    {
        cout
<< " pCompare != NULL " << "  pComapre =  " << pCompare << endl;
    }

    cout
<< " Compare the pointer function. " << endl;
    cout
<< " The compare result is :  " <<
        myCompare1(
6 5 , realCompare) << endl;

    cout
<< " It's the same to invoke realCompare & *realCompare :  " <<
        myCompare1(
6 5 * realCompare) << endl;

    cout
<< " Using the typedef to predigest definition :  " <<
        myCompare2(
8 7 , realCompare) << endl;

    cout
<< " Return a pointer from a function :  " <<
        myCompare2(
10 20 , getAPointerFunc1( true )) << endl;

    cout
<< " Return a pointer from a function :  " <<
        myCompare2(
20 30 , getAPointerFunc2( false )) << endl;

    
return  EXIT_SUCCESS;
}

int  myCompare1(
        
int  a,  int  b,
        
int  ( * Compare)( int int )){
    
return  Compare(a, b);
}
int  realCompare( int  a,  int  b){
    cout
<< " The realCompare has be invoked. " << endl;
    
if (a  ==  b)
        
return   0 ;
    
if (a  <  b)
        
return   - 1 ;
    
else
        
return   1 ;
}

int  fakeCompare( int  a,  int  b){
    cout
<< " The fackCompare has be invoked. " << endl;
    
return   200 ;
}

int  myCompare2(
        
int  a,  int  b,
        PF Compare){
    
return  Compare(a, b);
}

PF getAPointerFunc1(
bool  real){
    
if (real)
        
return  realCompare;
    
else   return  fakeCompare;
}

int  ( * getAPointerFunc2( bool  real))( int int ){
    
if (real)
        
return  realCompare;
    
else   return  fakeCompare;
}

 



只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理