指向成员函数的指针

 在此,成员函数指的是非静态的成员函数。

1、定义

    class Shape
    {
      public:
        //...
        void moveTo( Point newLocation );
        bool validate() const;
        virtual bool draw() const = 0;
        //...
    };
    class Circle : public Shape
    {
        //...
        bool draw() const;
        //...
    };
    //...
    void (Shape::*mf1)( Point ) = &Shape::moveTo; //指向成员函数的指针
    bool (Shape::*mf2)() const = &Shape::validate;//指向成员函数的指针

    比较一下就可以发现,指向成员函数的指针的声明与其所要指向的成员函数的声明是一致的,
无论是返回类型,参数,还是const属性。

2、含义
这一点与类数据成员的指针是一致的,是一个偏移量

3、使用
同指向类数据成员的指针使用方法一样,指向成员函数的指针也需要一个具体的对象的地址,然后加上偏移量,才能够得到对应的成员函数:

    Circle circ;
    Shape *pShape = ˆ
    (pShape->*mf2)(); // call Shape::validate
    (circ.*mf2)(); // call Shape::validate

看着那一对一对的括号,是否感觉到眼花缭乱了呢?那都得怪罪"->*"和".*"的优先级没有"()"的高。

4、当虚成员函数出现时:
由于“虚”只是成员函数本身的一个属性,所以就没有指向成员函数的虚指针,因此就有如下:

    mf2 = &Shape::draw; // draw is virtual
    (pShape->*mf2)();  // call Circle::draw

可以这样理解:pShape指向Circle类的对象circ,所以(pShape->*mf2)()就调用Circle::draw,尽管
mf2赋的值是父类Shape的虚成员函数。

这在内部是如何实现的呢?
指向成员函数的指针保存了如下信息:
    1)它指向的成员函数是否为虚的
    2)虚函数表的人口点
    3)相对于函数的this指针的偏移量(或加或减)
有了以上信息,就可以调用pShape所指向的对象的虚函数了。

5、当继承出现时:
还是那句话:子类有的父类未必有。

    class B
    {
      public:
        void bset( int val ) { bval_ = val; }
      private
        int bval_;
    };
    class D : public B
    {
      public:
        void dset( int val ) { dval_ = val; }
      private:
        int dval_;
    };
    B b;
    D d;
    void (B::*f1)(int) = &D::dset; // error
    (b.*f1)(12); // error
    void (D::*f2)(int) = &B::bset; // OK
    (d.*f2)(11); // OK
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值