指向类成员

来源:互联网 发布:php isset 编辑:程序博客网 时间:2024/05/16 05:26

使用指针指向类成员的非静态成员首先需要明确指向的类类型。

为什么呢?

1.先明确内存结构

对于类的非静态成员函数的参数列表在编译期,会加入一个 this* 指针,指向当前类实例。

因为函数在内存中只存在一份,存在多份的是数据成员。通过this* 指针我们可以访问到具体实例的数据成员。

想象一下:在内存中应该存在这样两个内存空间。

一个是Say类型的共用空间,各个实例共用的。存放静态数据成员,和所有函数成员。

一个是实例化一个Say类型后分配的空间。每个实例私有的,包含各自非静态数据成员。

当外部调用

Say s=new Say();

s->SayHell();

实际是通过 将s的地址赋予this*。这样在SayHell()内部就可以访问到当前实例的非静态数据成员。

2.怎样定义指向类成员变量的指针。

我们如何使用指向类非静态成员的指针?

(*prt)() = &Say::SayHell;  //假设正确。 

Say s=new Say();

(s->*prt)();   //实际上指向了内存中成员函数存在的位置,并将s的地址赋予this

这和普通函数指针的使用是有区别的:

普通函数指针的使用:

SayHi(){}; //注意是全局函数

(*prt)() = SayHi;

(*prt)() ; //使用

显然区别在于,因为使用类非静态成员,必须通过实例化得对象或者对象指针访问(上述第1点说明了原因),所以在编译期必须对函数指针的表现形式做扩展,使编译器能够理解这种有别于普通函数指针的情况。

于是

(Say::*prt)() = &Say::SayHell;  //正确的声明。 

Say s=new Say();

(s->*prt)(); 

通过这样的定义使编译器可以区分是否是指向类的成员。并使编译器检查必须使用一个实例化的Say的对象或者指向对象的指针来调用成员函数指针。

3.对于静态成员

由于静态成员是共用的,只存在一份。所以对于静态的成员函数不存在this*,所以不需要在调用使用关联对象的实例。所以可以像调用普通函数一样调用:

class Say

{

 public:

        static void SayHell()

};

(*prt)() = &Say::SayHell;  //正确的声明。 

(*prt)();