在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++——将成员函数作为参数
时间: 2024-10-13 02:34:28
C++——将成员函数作为参数的相关文章
c++中成员函数的参数名与成员变量名重合的问题
有一天写类的时候突然想到了这个问题,下面就来介绍如何解决这个问题. 定义一个类: class test{ public: void setnum(); void getnum(); private: int num; }; void test::setnum(){ num = 10; } void test::getnum(){ printf("%d\n",num); } 运行: int main() { test one; one.setnum(); one.getnum(); re
linux 之 pthread_create 实现类的成员函数做参数
在C++的类中,普通成员函数不能作为pthread_create的线程函数,如果要作为pthread_create中的线程函数,必须是static ! 在C语言中,我们使用pthread_create创建线程,线程函数是一个全局函数,所以在C++中,创建线程时,也应该使用一个全局函数.static定义的类的成员函数就是一个全局函数. class Thread { private: pthread_t pid; private: static void * start_thread(void *a
C++ 类成员函数作为参数
1 #include <iostream> 2 using namespace std; 3 4 typedef int int32_t; 5 6 struct IMsgBody{ 7 int body; 8 }; 9 10 struct Arg{ 11 int arg; 12 }; 13 14 class A; 15 16 typedef int32_t (A::*GetArg_Fun)(IMsgBody *pMsgBody, Arg *stArg); //函数指针 17 18 class
c++ 常量成员函数
结合个人的读书理解,做下常量成员函数的笔记. 常量成员函数的形式很简单,就是函数的声明定义后跟上一个const,如 class Test { public: int getData() const; private: int data; }; int Test::getData() const { return data; } int getData() const;就是一个常量成员函数了. 为什么加上一个const就把成员函数变为常量成员函数呢?const关键字到底做了什么? 按照<c++ p
C++类的成员函数的指针和mem_fun适配器的用法
一.普通函数指针 我们先来看一个最简单的函数: void fool(int a) { cout << a<< endl; } 那么它的函数指针类型为: void (*) (int) 我们可以这样测试: void (*pFunc)(int) = &foo;//这里pFunc是个指针 pFunc(123); 这样就会打印出整数123:为了简化,我们可以使用typedef: typedef void (*pFunc)(int); 这里我们要说明一下: 这里的pFunc是 返回值为
C++:类的成员函数定义方式
1.成员函数的第一种定义方式:在类声明中只给出成员函数的原型,而将成员函数的定义 放在类的外部. 返回值类型 类名::成员函数名(参数表) { 函数体 } class Point{ public: void setpoint(int,int); //设置坐标点的成员函数setpoint的函数原型 int getx(); //取x坐标点的成员函数getx的函数原型 int gety(); //取y坐标点的成员函数gety的函数原型 private: int x,y; }; void P
6——在类的外部定义成员函数
在类定义的外部定义成员函数时,应使用作用域操作符(::)来标识函数所属的类. 即有如下形式: 返回类型 类名::成员函数名(参数列表) { 函数体 } 其中,返回类型.成员函数名和参数列表必须与类定义时的函数原型一致. //Computer.h class Computer //类定义,起到接口作用 { private: char brand[20]; float price; public: //3个public成员函数的原型声明 void print(); void SetBrand(cha
成员函数指针与高性能的C++委托
成员函数指针与高性能的C++委托(上篇) 撰文:Don Clugston 引子 标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做"闭包(closure)"或"委托 (delegate)")在一些语言中已经证明了它宝贵的价值.在Delphi (Object Pascal)中,面向对象的函数指针是Borland可视化组建库(VCL,Visual Component Library)的基础.而在目前,C#使"委托&
类 this指针 const成员函数
C++ Primer 第07章 类 7.1.2 ?Sales_data类的定义如下: #ifndef SALES_DATA_H #define SALES_DATA_H #include <string> #include <iostream> class Sales_data { public: std::string isbn() const {return bookNo;} Sales_data& combine(const Sales_data&); dou