您的位置:首页 > 其它

类的普通成员函数的指针

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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: