类成员指针

  • Post author:
  • Post category:其他




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

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


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

例如,设有如下一个类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. 指向类的成员的指针



版权声明:本文为winsbb原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。