在C++中,成员函数指针作为参数传递给其他函数和普通函数指针的传递是不同的,首先 
我们来回顾一下普通函数指针的传递方法: 
//-------------------------------------------------------------------------- 
int fun1(int i){ 
         return i; 

void fun2(int j, int (*p)(int)){ 
         cout << p(j); 

void main() 

         int i=1; 
         fun2(i,fun1); 

//-------------------------------------------------------------------------- 
  
只要在参数声明中声明是相同参数个数、类型和相同返回类型的函数指针int (*p)(int 
),传递时只需传函数名就可以了可是为什么在C++中,传递成员函数指针用此方法却不 
能工作呢?我们先来回顾一下指针的概念,指针是指向一些内存地址的变量,既可以是 
数据的地址也可以是函数的地址。C++的成员指针遵从同样的原则。困难的是所有的指针 
需要一个地址,但在类内部没有地址;选择一个类的成员意味着在类中偏移。只有把这 
个偏移和具体对象的开始地址结合,才能得到实际地址。成员指针的语法要求选择一个 
对象的同时逆向引用成员指针。先来看看一个错误的例子: 
//-------------------------------------------------------------------------- 
class A 

public: 
         int fun1(int i){return i;}; 
}; 
void fun2(int j, int (A::*p)(int)){ 
         cout <<p(j); 

void main() 

         A oba; 
         int i=1; 
         fun2(i,oba.fun1);  //this is an error 

//-------------------------------------------------------------------------- 
  
当然,你可以把成员函数声明为static(静态函数),这样传递它的指针就像传递普通 
函数一样,然而把成员函数定义成static类型无法真正解决问题,因为这样的话,该成 
员函数就不能存取类中的非静态成员变量,而很多情况下既要求传递成员函数指针,又 
要求该成员函数能够存取类中的非静态成员变量。 
为了能够正确地传递成员函数指针,我们先来看看成员参数、成员函数指针正确的声明 
方法: 
//-------------------------------------------------------------------------- 
class A 

public: 
         int i1; 
         int fun1(int i){ 
                 return i; 
         }; 
}; 
void main() 

         int (A::*fp1)(int);    //声明fp1为class A中的成员函数指针 
         int A::*ip1;           //声明ip1为class A中的成员变量指针 
         fp1=&A::fun1;          //初始化fp1 
         ip1=&A::i1;            //初始化ip1 
         ip1=&A::i1;            //初始化ip1 
         A oba; 
         oba.*ip1=2; 
         (oba.*fp1)(oba.*ip1); 

//-------------------------------------------------------------------------- 
  
接下来就可以构造含有成员函数指针参数的函数了: 
void fun2(int j, A ob, int (A::*p)(int)){ 
         cout <<(ob.*p)(j); 

注意声明时必须加上一个对象参数A ob,因为只有把这个偏移和具体对象的开始地址结 
合,才能得到实际地址。 
  
另外,为了保证函数的健壮性和经济性,我们可以把对象参数改为对象指针参数: 
void fun2(int j, A *obp, int (A::*p)(int)){ 
         cout <<(obp->*p)(j); 

  
为了通用,我们还可以把这个函数声明为通用函数: 
template <class T> 
void fun2(int j, T *obp, int (A::*p)(int)){ 
         cout <<(obp->*p)(j); 

  
这样就可以传递不同的类的成员函数指针给它了,以下为正确传递成员函数指针的例程: 
//-------------------------------------------------------------------------- 
class A 

public: 
         int fun1(int i){ 
                 return i; 
         }; 
}; 
template <class T> 
void fun2(int j, T *obp, int (T::*p)(int)){ 
         cout <<(obp->*p)(j); 

void main() 

         int (A::*fp1)(int); 
         fp1=&A::fun1; 
         A oba; 
         A *obap=&oba; 
         int i=1; 
         fun2(i,obap,fp1); 

//-------------------------------------------------------------------------- 
  
但是这样声明之后就不能再传递普通函数指针给函数fun2了,为了更加通用,当然可以 
显式地重载一下这个函数,以便它也能使用普通函数指针参数: 
//-------------------------------------------------------------------------- 
class A 

public: 
         int fun1(int i){ 
                 return i; 
         }; 
}; 
template <class T> 
void fun2(int j, T *obp, int (T::*p)(int)){ 
         cout <<(obp->*p)(j); 

void fun2(int j, int (*p)(int)){ 
         cout << p(j); 

int fun3(int i){ 
         return i; 

void main() 

         int (A::*fp1)(int); 
         fp1=&A::fun1; 
         A oba; 
         A *obap=&oba; 
         int i=1; 
         fun2(i,obap,fp1); 
         fun2(i,fun3); 

//--------------------------------------------------------------------------

C++——将成员函数作为参数的更多相关文章

  1. c++中成员函数的参数名与成员变量名重合的问题

    有一天写类的时候突然想到了这个问题,下面就来介绍如何解决这个问题. 定义一个类: class test{ public: void setnum(); void getnum(); private: ...

  2. linux 之 pthread_create 实现类的成员函数做参数

    在C++的类中,普通成员函数不能作为pthread_create的线程函数,如果要作为pthread_create中的线程函数,必须是static ! 在C语言中,我们使用pthread_create ...

  3. C++ 类成员函数作为参数

    #include <iostream> using namespace std; typedef int int32_t; struct IMsgBody{ int body; }; st ...

  4. Javascript基础--成员函数(六)

    成员函数:也叫方法 1.常用方法 比如:我们希望对象不但有属性,还希望他有行为.(行为在程序中要靠函数来体现)(1) 添加speak函数,输出我是一个好人 (2) 添加jisuan函数,可以计算从1+ ...

  5. C++:类的成员函数定义方式

    1.成员函数的第一种定义方式:在类声明中只给出成员函数的原型,而将成员函数的定义 放在类的外部. 返回值类型 类名::成员函数名(参数表) {      函数体  } class Point{ pub ...

  6. 类 this指针 const成员函数

    C++ Primer 第07章 类 7.1.2 ​Sales_data类的定义如下: #ifndef SALES_DATA_H #define SALES_DATA_H #include <st ...

  7. C++中的const成员函数(函数声明后加const,或称常量成员函数)用法详解

    http://blog.csdn.net/gmstart/article/details/7046140 在C++的类定义里面,可以看到类似下面的定义: 01 class List { 02 priv ...

  8. 介绍了如何取成员函数的地址以及调用该地址:C++

    摘要:介绍了如何取成员函数的地址以及调用该地址. 关键字:C++成员函数 this指针 调用约定 一.成员函数指针的用法 在C++中,成员函数的指针是个比较特殊的东西.对普通的函数指针来说,可以视为一 ...

  9. const当做标记的函数重载,但是仅仅是限于类里面的成员函数

    (1)我们知道函数的重载时根据函数的参数类型以及函数参数个数来重载的,不能用函数返回值来重载函数.但是有时候函数参数个数和函数参数类型重载函数会和默认参数发生冲突: int fun(int i,cha ...

随机推荐

  1. 20150608_Andriod 发布方法

    参考地址: http://www.jb51.net/article/42618.htm 第一步,在Eclipse中选择需要打包的项目,然后右键--选择Export,会弹出一个打包的提示框,如下图所示. ...

  2. Android GridView 第一个Item 点击没反应

    @Override public View getView(final int position, View convertView, ViewGroup parent) { final ViewHo ...

  3. Task schedule 分类: 比赛 HDU 查找 2015-08-08 16:00 2人阅读 评论(0) 收藏

    Task schedule Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...

  4. servlet中Java连接数据库后的基本操作

    servlet中Java连接数据库后的基本操作 在eclipse中新建一个工程:login 在Server中新建一个服务器,基本的操作不用说了,在前两天的笔记中可以找到; 需要知道数据库的用户名和密码 ...

  5. COM技术の组件

    什么是COM COM,Component Object Mode即组件对象模型.之所以称之为“模型”,是表明COM是一种编程规范(非具体代码),通过这种规范我们能够编写出语言无关的,可扩展的,内部变化 ...

  6. [kipmi0]进程导致系统负载高

    最近一个用户这边服务器运行四五天就会出现服务器负载很高的情况,原本正常是0.3~0.5左右  不正常的时候会达到3,重启机器就正常,开始以为是程序问题,后来在观察的时候把程序给杀掉了 然后重启,结果负 ...

  7. Spring.Net 技术简介 IOC and DI

    一 简单介绍            IOC 控制转移,就是将创建放到容器里,从而达到接耦合的目的,DI是 在容器创建对象的时候,DI读取配置文件,然后给对象赋默认值,两者一般结合使用,实现注入.   ...

  8. white的配置使用

    初次使用White来自动化测试10个9相加1.新建Visual C#->测试->单元测试项目2.在资源视图->引用,右键,添加引用,添加White的两个.dll文件3.在工程中添加命 ...

  9. Struts2的输入校验(2)——客户端校验

    Struts2的输入校验(2) --客户端校验 Struts2客户端校验的使用: (1)使用Struts2的标签生成输入页面的表单: (2)为该<s:form>元素添加validate=& ...

  10. linux下(修改|忘记)mysql密码

    好尴尬,经常忘记自己的密码 修改的用户都以root为列.一.拥有原来的myql的root的密码: 方法一:在mysql系统外,使用mysqladmin# mysqladmin -u root -p p ...