类的普通成员函数的指针
2010-03-09 16:47
169 查看
很
多朋友都知道虚函数有虚函数指针,并且存放在对象的虚函数表中,它和普通成员变量一样与对象相关,因此虚函数的指针是和对象级的。一个类的普通成员函数是
类级的,因此普通成员函数的指针也是类级的。一个类的普通成员函数的指针,少有文献提及,因为很少需要用到普通成员函数的指针。尽管如此,在一些特殊的场
合,还是有可能需要用到的。
1)
成员函数简介
在
C++
中,成员函数的指针是个比较特殊的东西。对普通的函数指针来说,可以视为一个地址
,
在需要的时候可以任意转换并直接调用。但对成员函数来说,常规类型转换是通不过编译的,调用的时候也必须采用特殊的语法。
C++
专门为成员指针准备了三个运算符
: "::*"
用于指针的声明,而
"->*"
和
".*"
用来调用指针指向的函数。比如
:
#include <iostream>
using namespace std;
class Foo
{
public:
double virtual One( long inVal );
double virtual Two( long inVal );
};
double Foo::One(long inVal)
{
return inVal;
}
double Foo::Two(long inVal)
{
return inVal;
}
//
定义一个指向成员函数的指针类型,这些成员函数的返回值类型应该是
double
,并且有一个
long
类型的参数。
typedef double (Foo::*PMF)(long);
//
定义一个以对象调用函数指针的方法,其中:
obj
:调用成员函数指针的对象;
pointer
:成员函数的指针。
//
注意:因为
".*"
优先级较低,所以该符号的两端,均需加上括号
#define callmemfun(obj, pointer) ((obj).*(pointer))
//
定义一个以对象指针调用函数指针的方法,其中:
pobj
:调用成员函数指针的对象指针;
pointer
:成员函数的指针。
//
注意:因为
"->*"
优先级较低,所以该符号的两端,均需加上括号
#define pcallmemfun(pobj, pointer) ((pobj)->*(pointer))
int main(void)
{
Foo aFoo;
//
注意:获取一个成员函数指针的语法要求很严格
// 1.
不能使用括号,比如
PMF pmf = &(Foo::Two)
是错误的
// 2.
必须有类限定符,如
PMF pmf = &Two
是错误的,
即使是在类定义的内部也须加上类限定符,
即
PMF pmf = &Foot::Two
// 3.
必须使用取址符号:比如
PMF pmf = Foo::Two
是错误的,虽然普通函数指针可以这样
(
其实对以成员函数指针,某些编
//
译器也是允许这样,但最好还是加上取址符号
)
,应该写成
PMF pmf = &Foot::Two
PMF pmf = &Foo::Two;
//
取成员函数指针
double result = callmemfun(aFoo, pmf)(2);
cout << result << endl;
result = pcallmemfun(&aFoo, pmf)(3);
cout << result << endl;
return 0;
}
无
法将成员函数类型转换为其它任何稍有不同的类型,简单的说,每个成员函数指针都是一个独有的类型,无法转换到任何其它类型。即使两个类的定义完全相同也不
能在其对应成员函数指针之间做转换。这有点类似于结构体的类型,每个结构体都是唯一的类型,但不同的是,结构体指针的类型是可以强制转换的。有了这些特殊
的用法和严格的限制之后,类成员函数的指针实际上是变得没什么用了。这就是我们平常基本看不到代码里有
"::*", ".*"
和
"->*"
的原因。
2)
使用成员函数指针访问类的私有成员函数
#include <iostream>
using namespace std;
class Foo;
typedef double (Foo::*PMF)(long);
#define callmemfun(obj, pointer) ((obj).*(obj.pointer))
#define pcallmemfun(pobj, pointer) ((pobj)->*(pobj->pointer))
class Foo
{
public:
PMF pmf;
Foo()
{
pmf = &Foo::Three;
//
取得私有成员函数的指针
}
public:
inline double One(long inVal)
{
return inVal;
}
inline double Two(long inVal)
{
return 2 * inVal;
}
private:
inline double Three(long inVal)
{
cout << "this is in Three..." << endl;
return 3 * inVal;
}
};
int main(void)
{
Foo aFoo;
Foo* bFoo = new Foo;
//
通过公有成员变量
pmf
,很轻松地调用了私有成员函数
Three
callmemfun(aFoo, aFoo.pmf)(3);
pcallmemfun(bFoo, bFoo->pmf)(4);
((aFoo).*(aFoo.pmf))(3);
return 0;
}
多朋友都知道虚函数有虚函数指针,并且存放在对象的虚函数表中,它和普通成员变量一样与对象相关,因此虚函数的指针是和对象级的。一个类的普通成员函数是
类级的,因此普通成员函数的指针也是类级的。一个类的普通成员函数的指针,少有文献提及,因为很少需要用到普通成员函数的指针。尽管如此,在一些特殊的场
合,还是有可能需要用到的。
1)
成员函数简介
在
C++
中,成员函数的指针是个比较特殊的东西。对普通的函数指针来说,可以视为一个地址
,
在需要的时候可以任意转换并直接调用。但对成员函数来说,常规类型转换是通不过编译的,调用的时候也必须采用特殊的语法。
C++
专门为成员指针准备了三个运算符
: "::*"
用于指针的声明,而
"->*"
和
".*"
用来调用指针指向的函数。比如
:
#include <iostream>
using namespace std;
class Foo
{
public:
double virtual One( long inVal );
double virtual Two( long inVal );
};
double Foo::One(long inVal)
{
return inVal;
}
double Foo::Two(long inVal)
{
return inVal;
}
//
定义一个指向成员函数的指针类型,这些成员函数的返回值类型应该是
double
,并且有一个
long
类型的参数。
typedef double (Foo::*PMF)(long);
//
定义一个以对象调用函数指针的方法,其中:
obj
:调用成员函数指针的对象;
pointer
:成员函数的指针。
//
注意:因为
".*"
优先级较低,所以该符号的两端,均需加上括号
#define callmemfun(obj, pointer) ((obj).*(pointer))
//
定义一个以对象指针调用函数指针的方法,其中:
pobj
:调用成员函数指针的对象指针;
pointer
:成员函数的指针。
//
注意:因为
"->*"
优先级较低,所以该符号的两端,均需加上括号
#define pcallmemfun(pobj, pointer) ((pobj)->*(pointer))
int main(void)
{
Foo aFoo;
//
注意:获取一个成员函数指针的语法要求很严格
// 1.
不能使用括号,比如
PMF pmf = &(Foo::Two)
是错误的
// 2.
必须有类限定符,如
PMF pmf = &Two
是错误的,
即使是在类定义的内部也须加上类限定符,
即
PMF pmf = &Foot::Two
// 3.
必须使用取址符号:比如
PMF pmf = Foo::Two
是错误的,虽然普通函数指针可以这样
(
其实对以成员函数指针,某些编
//
译器也是允许这样,但最好还是加上取址符号
)
,应该写成
PMF pmf = &Foot::Two
PMF pmf = &Foo::Two;
//
取成员函数指针
double result = callmemfun(aFoo, pmf)(2);
cout << result << endl;
result = pcallmemfun(&aFoo, pmf)(3);
cout << result << endl;
return 0;
}
无
法将成员函数类型转换为其它任何稍有不同的类型,简单的说,每个成员函数指针都是一个独有的类型,无法转换到任何其它类型。即使两个类的定义完全相同也不
能在其对应成员函数指针之间做转换。这有点类似于结构体的类型,每个结构体都是唯一的类型,但不同的是,结构体指针的类型是可以强制转换的。有了这些特殊
的用法和严格的限制之后,类成员函数的指针实际上是变得没什么用了。这就是我们平常基本看不到代码里有
"::*", ".*"
和
"->*"
的原因。
2)
使用成员函数指针访问类的私有成员函数
#include <iostream>
using namespace std;
class Foo;
typedef double (Foo::*PMF)(long);
#define callmemfun(obj, pointer) ((obj).*(obj.pointer))
#define pcallmemfun(pobj, pointer) ((pobj)->*(pobj->pointer))
class Foo
{
public:
PMF pmf;
Foo()
{
pmf = &Foo::Three;
//
取得私有成员函数的指针
}
public:
inline double One(long inVal)
{
return inVal;
}
inline double Two(long inVal)
{
return 2 * inVal;
}
private:
inline double Three(long inVal)
{
cout << "this is in Three..." << endl;
return 3 * inVal;
}
};
int main(void)
{
Foo aFoo;
Foo* bFoo = new Foo;
//
通过公有成员变量
pmf
,很轻松地调用了私有成员函数
Three
callmemfun(aFoo, aFoo.pmf)(3);
pcallmemfun(bFoo, bFoo->pmf)(4);
((aFoo).*(aFoo.pmf))(3);
return 0;
}
相关文章推荐
- 使用std::function 把类成员函数指针转换为普通函数指针
- C++中通过派生类调用第二基类的普通成员函数时this指针的调整
- 成员函数指针:(结构+与普通函数指针之间的转换)
- 类的普通成员函数的指针
- c++11调用成员函数mem_fn和适合普通函数指针
- 普通函数,成员函数,静态成员函数与【指针】
- 12-4-26关于普通函数指针,类成员函数指针,char(*)[]
- 类成员函数当作普通函数指针 用于callback
- 类的普通成员函数的指针
- MFC 外部普通函数获取类对象指针来调用类的成员函数
- 向普通函数传递类成员函数指针的问题
- 普通函数指针和指向成员函数指针
- 成员函数指针作为参数传递给其他函数和普通函数指针的传递
- 【解惑】函数名与函数指针(普通C/C++函数、C++类*静态*函数名取不取址都一样,但C++类成员函数必须取址)
- 向普通函数传递类成员函数指针的问题
- 普通函数指针与类成员函数指针的区别
- 类的成员函数指针作为参数传递给其他函数和普通函数指针的传递是不同的
- c++ 成员函数 普通函数指针转换
- 使用std::function 把类成员函数指针转换为普通函数指针
- C++点滴——const/volatile不能用来修饰没有this指针的成员函数