• Item 16. 指向成员函数的指针


    Item 16. Pointers to Member Functions Are Not Pointers


    Pointers to Member Functions :指向成员函数的指针
      在此,成员函数指的是非静态的成员函数。
      Pointers to state Member Functions Are Pointers
    ----------------------------------------------------
    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); // 不合法
    void (D::*f2)(int) = &B::bset; // OK
    (d.*f2)(11); // OK


     
     

  • 相关阅读:
    详述@Responsebody和HTTP异步请求的关系
    利用synchronized解析死锁的一种形成方式
    初识Spring JdbcTemplate
    初识SpringIOC
    JasperReport框架使用教程(附带常见空白页问题说明)
    LeetCode~1033.移动石子直到连续
    LeetCode~941.有效的山脉数组
    LeetCode~344. 反转字符串
    Job for network.service failed because the control process exited with error code问题
    LeetCode~报数(简单)
  • 原文地址:https://www.cnblogs.com/aiwz/p/6333244.html
Copyright © 2020-2023  润新知