• C++中的类成员指针


    写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文!

    本博客全网唯一合法URL:http://www.cnblogs.com/acm-icpcer/p/6729273.html

    C++中的类成员指针

      在上一篇文章中我提到了C++中的函数指针。那么如果想定义一个指向类数据成员或者函数成员的指针,又该怎么办呢?

      本质上讲和之前我提到的写法没有什么不同,只不过是要加上域定义而已。

    1.类数据成员指针

      例如,对于下面的类A:

    class A
    {
    public:
        int x;
        int sayhello()
        {
            cout<<"hello world"<<endl;
        }
    };

      假如我想定义一个指向数据成员x的指针,则:

      int A::*pointer1 = &A::x;

      很明显,去掉域定义其实就是普通的指针定义:int pointer1=&x;

      那么,如果用typedef来简化语法就是:

      typedef int A::*int_pointer;

      int_pointer pointer2 = &A::x;

      两者是等价的。

      调用指针时则为:

        A a;
        a.*pointer1 = 6;
        ++(a.*pointer2);
        cout << &a->*pointer1 << endl;

      结果为7。(注意:必须声明一个A的对象才可以调用类数据成员指针)

      那么这个类数据成员指针究竟是地址还是什么呢?

      为了搞清楚,我们就把它打出来看看吧:

      cout << pointer1 << endl << pointer2 << endl;

       结果是1    1。

      这是什么意思呢?实际上,类数据成员指针只是相对于对象在内存中初始地址的一个偏移量,也就是说,它是一个相对地址。

    2.类函数成员指针

      现在,我们讨论一下类函数成员指针的定义和使用。我们的讨论建立在以下类A和类B的基础上来讲:

    class A
    {
    private:
        int y;
    public:
        double w;
        int x;
        int sayhello()
        {
            cout<<"hello world"<<endl;
        }
    };
    
    class B:public A
    {
    
    };

      类成员函数指针定义:

      int (A::*classAfunctionpointer1)();

      classAfunctionpointer1 = &A::sayhello;

      可以看到,这其实也是在普通的全局函数指针前面加上了一个域定义而已(普通全局函数指针:int (*classAfunctionpointer1)();)。

      那么,如果用typedef来简化语法就是:

      typedef int (A::*FP)();

      FP classAfunctionpointer2 = &A::sayhello;

      调用时都是一样的:

      (a.*classAfunctionpointer1)();

      (a.*classAfunctionpointer2)();

      或者

      (&a->*classAfunctionpointer1)();

      (&a->*classAfunctionpointer2)();

      结果都是打印出hello world。(注意:类成员函数指针在使用前必须先声明一个对象)

      那么,类B继承了类A,理论上讲B也可以使用A的指针:

      B b;

      (b.*classAfunctionpointer1)();

      确实可以,结果也是打印出hello world。

      那么这又是为什么呢?

      实际上,类成员函数的地址是绝对的,因为类成员函数是定义在一个固定的代码区中。当年使用不同的对象去调用同一个类成员函数的时候,本质上,编译器会把该对象的this指针默认加在该成员函数的形参列表中,以便让函数明白是谁在调用它。所以不同的对象去调用同一个类成员函数的时候,编译器才能理解并作出反应。

      

    3.示例代码

      好了,根据上面讲到的所有基础知识,我给出如下程序:

    #include<iostream>
    using namespace std;
    
    class A
    {
    private:
        int y;
    public:
        double w;
        int x;
        int sayhello()
        {
            cout<<"hello world"<<endl;
        }
    };
    
    class B:public A
    {
    
    };
    
    typedef int A::*int_pointer;
    typedef int (A::*FP)();
    
    int main()
    {
        int A::*pointer1 = &A::x;
        int_pointer pointer2 = &A::x;
        A a;
        a.*pointer1 = 6;
        ++(a.*pointer2);
        cout << &a->*pointer1 << endl << pointer1 << endl << pointer2 << endl;
    
        double A::*pointer3 = &A::w;
        cout<<pointer3<<endl;
    
        B b;
        a.sayhello();
        int (A::*classAfunctionpointer1)();
        classAfunctionpointer1 = &A::sayhello;
        FP classAfunctionpointer2 = &A::sayhello;
        (a.*classAfunctionpointer1)();
        (a.*classAfunctionpointer2)();
        (&a->*classAfunctionpointer1)();
        (b.*classAfunctionpointer1)();
    
        return 0;
    }

    TZ

    2017/4/18于华中农业大学

  • 相关阅读:
    信号
    test
    keil4打开keil5工程卡死问题
    day01
    SSH问题
    QT_day02
    QT_day01
    C++_day9am
    文件描述符与重定向
    C++_day8pm_多态
  • 原文地址:https://www.cnblogs.com/acm-icpcer/p/6729273.html
Copyright © 2020-2023  润新知