1、概念:指向类中的数据成员或者成员函数的指针。
2、定义格式:
(1)指向数据成员的指针:
<变量类型> <类名>::* <指针名称>
eg:声明一个指向double类型数据成员的指针: double Transport::* pd;
可以用typedef来做同义替换:typedef double Transport::* pdouble; // pdouble表示 double Transport::*,则上述定义可简化为pdouble pd;
(2)指向成员函数的指针:
typedef 函数返回值类型(类名::* 指针名)(参数列表);
eg:声明一个指向Transport类中成员函数的指针:typedef void(Transport::*pfunc)(); //指针名为pfunc,指向的成员函数的放回值为void型,无参数带入
3、初始化
(1)初始化数据成员
typedef<span style="white-space: pre;"> double Transport::* p</span>double;
class Transport
{
public:
double d;
};
Transport t;
pdouble pd = &Transport::d; //定义初始化
t.*pd; //调用
class Father //定义基类
{
public:
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>Father(int a) //虚构造函数,这样在多个子类继承父类时只保留一个
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>age = a;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>virtual void print() //特别要注意此处在声明成员函数时一定要声明为虚函数,只有这样才能实现动态绑定,才能用类的成员
<span style="white-space:pre"> </span>{ //指针实现函数的选择与重载
<span style="white-space:pre"> </span>cout<<"in father function"<<endl;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>int age;
private:
};
<pre name="code" class="cpp">typedef void (Father:: *pprint)(); //声明成员函数指针
void main()
{
pprint ps = &Father::print; //初始化函数指针
}
4、实例:学会使用数据成员指针和函数对象指针
/******************************************************************
时间:2016年10月6日09:48:51
功能:学会使用类中的数据成员指针和函数成员指针
*******************************************************************/
#include <iostream>
using namespace std;
class Father //定义基类
{
public:
Father(int a) //虚构造函数,这样在多个子类继承父类时只保留一个
{
age = a;
}
virtual void print() //特别要注意此处在声明成员函数时一定要声明为虚函数,只有这样才能实现动态绑定,才能用类的成员
{ //指针实现函数的选择与重载
cout<<"in father function"<<endl;
}
int age;
private:
};
class Son : public Father //定义派生类son
{
public:
Son():Father(age)
{
}
void print()
{
cout<<"in son function"<<endl;
}
private:
};
class Daughter : public Father //定义派生类daughter
{
public:
Daughter():Father(age)
{
}
void print()
{
cout<<"in daughter function"<<endl;
}
private:
};
typedef int Father::* pint; //数据成员指针
typedef void (Father:: *pprint)(); //声明成员函数指针
void main()
{
Father ff(53);
pint pd = &Father::age; //初始化数据指针
pprint ps = &Father::print; //初始化函数指针
printf("pd = %d\n",pd); //输出偏移地址
cout<<"age is : "<<ff.*pd<<endl; //访问具体对象的内容
Son s; //定义对象
Daughter d;
Father *pf; //定义对象指针,由基类决定指向哪一个子对象
pf = &s; //初始化对象指针
(pf->*ps)();
pf = &d; //更换对象指针的指向
(pf->*ps)();
}
运行结果如下图:
总结:无论是数据成员指针还是函数成员指针,它们的实质都是指针,只是在使用这些指针的时候一定要加上限制,因为这些内容都是在某个类中的;另外一点要想实现动态绑定,一定要注意要将基类中的成员函数定义为虚基类。