类成员指针

指向类的数据成员的指针:

指向数据成员的指针格式如下:

<类型说明符><类名>::*<指针名>

例如,设有如下一个类A:

class A
{
public:
    int fun (int b) { return a * c + b; }
    A(int i) { a = i; }
    int c;
private:
    int a;
};

定义一个指向类A的数据成员c的指针pc,其格式如下:

int A:: *pc = &A::c;

再定义一个指向类A的成员函数fun的指针pfun,其格式如下:
int (A:: *pfun)(int) = A::fun;

由于类不是运行时存在的对象。因此,在使用这类指针时,需要首先指定A类的一个对象,然后,通过对象来引用指针所指向的成员。例如,给pc指针所指向的数据成员c赋值8,可以表示如下:

A a;
a.*pc = 8;

其中,运算符.*是用来对指向类成员的指针来操作该类的对象的。

如果使用指向对象的指针来对指向类成员的指针进行操作时,使用运算符->*。例如:

A *p = &a;
p->*pc = 8;

指向类的数据成员的指针并非指针,因为它既不包含地址,行为也不像指针。

与常规指针不同,一个指向成员的指针并不指向一个具体的内存位置,它指向的是一个类的特定成员,而不是指向一个特定对象里的特定成员。

通常最清晰的做法是将指向数据成员的指针看作为一个偏移量

C++标准并没有说该如何实现指向成员的指针,大多数编译器都将指向数据成员的指针实现为一个整数,其中包含被指向成员的偏移量。另外加上1(加1是为了让0值可以表示一个空的数据成员指针)。

这个偏移量告诉你,一个特定成员的位置距离对象的起点有多少个字节。一个类成员的偏移量在任何对象中都是相同的。

给定一个成员在类内的偏移量,为了访问位于那个偏移量的数据成员,我们需要该类的一个对象的地址。这时候就需要 .*->* 这两个看上去非同寻常的操作符闪亮登场了。

class C 
{  
public:        
   int a_;  
};  
 
int C::*pimC; // 一个指针,指向C的一个int成员  
C aC;  
C* pC = &aC;  
pimC = &C::a_; //::的优先级高于&  
aC.*pimC = 0;  
int b = pC -> *pimC;

当写下pC->*pimC时,其实是请求将pC内的地址加上pimC内的偏移量,为的是访问pC所指向的C对象中适当的数据成员。

当写aC.*pimC时,是在请求aC的地址加上pimC中的偏离量,也是为了访问pC所指向的C对象中适当的数据成员。

指向类的成员函数的指针:

指向成员函数的指针格式如下:

<类型说明符>(<类名>::*<指针名>)(<参数表>)

下面给出一个使用指向类成员指针的例子:

#include <iostream.h>
class A
{
public:
    A(int i) { a = i; }
    int fun(int b) { return a * c + b; }
    int c;
private:
    int a;
 };
 
int main()
{
    A x(8);               //定义类A的一个对象x
    int A::*pc;           //定义一个指向类数据成员的指针pc
    pc = &A::c;            //给指针pc赋值
    x.*pc = 3;             //用指针方式给类成员c赋值为3
    int (A::*pfun)(int);   //定义一个指向类成员函数的指针pfun
    pfun = &A::fun;         //给指针pfun赋值   需要&符!!!
    A *p = &x;             //定义一个对象指针p,并赋初值为x
    cout<<(p->*pfun)(5)<<endl;    //用对象指针调用指向类成员函数指针pfun指向的函数
    return 0;
}

总结:

类成员指针指向的不是实际数据,使用类成员指针需要绑定到具体对象。

初始化一个成员指针或者为一个成员指针赋值时,该指针没有指向任何数据。成员指针指定了成员而非该成员所属的对象,只有当解引用成员指针时我们才提供对象。

参考文献:

  1. C++ primer 第5版 ch19.4
  2. 指向类的成员的指针
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值