zoukankan      html  css  js  c++  java
  • 指向类的数据成员和函数指针

    指向类成员的指针

    在C++语言中,可以定义一个指针,使其指向类成员或成员函数,然后通过指针来访问类的成员。这包括指向属性成员的指针和指向成员函数的指针。

    à 指向数据成员的指针

    在C++语言中,可以定义一个指针,使其指向类成员。当属性成员为静态和非静态时,指针的使用也有不同。其中,指向非静态数据成员的指针定义格式如下:

    1.    <数据类型> <类名>::*<指针名> [ = &<类名>::<非静态数据成员>] 

    指向非静态数据成员的指针在定义时必须和类相关联,在使用时必须和具体的对象关联。

    2.    <类对象名>.*<指向非静态数据成员的指针> 

    指向静态数据成员的指针的定义和使用与普通指针相同,在定义时无须和类相关联,在使用时也无须和具体的对象相关联。

    假设已经定义了一个类student,该类有非静态成员math,静态成员chinese,代码演示了指向它们的指针定义方式。

    1.           student s1;  
    2.           int student::*pm=&student::math;    //指向非静态属性  
    3.           s1.*pm=100;                         //设置非静态属性  
    4.           int *pc=&student::chinese;          //指向静态属性  
    5.           *pc=10;                             //设置静态属性 

    分析:该示例定义了指针pc和pm,分别指向类的静态数据成员chinese和非静态数据成员math。访问pm时,必须使用类实例来修饰。而访问pc时,与普通指针没有区别。

    à 指向成员函数的指针

    定义一个指向非静态成员函数的指针必须在三个方面与其指向的成员函数保持一致:参数列表要相同、返回类型要相同、所属的类型要相同。定义格式如下:

    1.    <数据类型>(<类名>::*<指针名>)(<参数列表>)[=&<类名>::<非静态成员函数>] 

    使用指向非静态成员函数的指针的方法和使用指向非静态数据成员的指针的方法相同,格式如下:

    2.    (<类对象名>.*<指向非静态成员函数的指针>)(<参数列表>); 

    指向静态成员函数的指针和普通指针相同,在定义时无须和类相关联,在使用时也无须和具体的对象相关联。

    3.    <数据类型>(*<指针名>)(<参数列表>)[=&<类名>::<静态成员函数>] 

    假设类student有非静态成员函数f1,非静态成员函数f2,代码演示指向它们的函数指针的定义方式。

    1.           student s1;  
    2.           float (student::*pf1)()=&student::f1;       //指向非静态成员函数的指针  
    3.           (s1.*pf1)();                 //调用指向非静态成员函数的指针  
    4.           void (*pf2)()=&student::f2;  //指向静态成员函数的指针  
    5.           pf2();                       //调用静态成员函数 

    分析:指向非静态成员函数时,必须用类名作限定符,使用时则必须用类的实例作限定符。指向静态成员函数时,则不需要使用类名作限定符。

    分析:

    pointName = &ClassName::member;

    即将类中指定成员的地址赋给指针变量,其中ClassName是已定义的类名,而member是数据成员名。显然,编译系统对类名并不分配存储空间,也就没有一个绝对地址。所以这种赋值,是取该成员相对于该类的所在对象中的偏移量,即相对地址(距离开始位置的字节数)。对类中的任一成员,其偏移量是一个常数。

    因这种指针变量的值是一个相对地址,不是指向某一个对象中的数据成员的绝对地址,所以不能单独使用这种指针变量来访问数据成员。如*pointName 是不允许的。由于这种指针变量并不是类的成员,所以使用它只能访问对象的公有数据成员。若要访问对象的私有数据成员,必须通过成员函数来实现。

    实例如下:

    1. #include <iostream>  
    2. using namespace std;  
    3.   
    4. class Point3d  
    5. {  
    6. public:  
    7.     Point3d(){x = y = z = -1;}  
    8.     float sum(){return x+y+z;}  
    9. public:  
    10.     float x,y,z;  
    11.     static float s;  
    12. };  
    13.   
    14. float Point3d::s = 100;  
    15.   
    16. int main () {  
    17.     cout<<Point3d::s<<endl;  
    18.   
    19.     Point3d p3d;  
    20.     float Point3d::*pfm = &Point3d::x;  
    21.     cout<<p3d.*pfm<<endl;  
    22.   
    23.     float *pfsm = &Point3d::s;  
    24.     cout<<*pfsm<<endl;  
    25.   
    26.     float (Point3d::*pff)() = &Point3d::sum;  
    27.     cout<<(p3d.*pff)()<<endl;  
    28. }  
    #include <iostream>
    using namespace std;
    
    class Point3d
    {
    public:
    	Point3d(){x = y = z = -1;}
    	float sum(){return x+y+z;}
    public:
    	float x,y,z;
    	static float s;
    };
    
    float Point3d::s = 100;
    
    int main () {
    	cout<<Point3d::s<<endl;
    
    	Point3d p3d;
    	float Point3d::*pfm = &Point3d::x;
    	cout<<p3d.*pfm<<endl;
    
    	float *pfsm = &Point3d::s;
    	cout<<*pfsm<<endl;
    
    	float (Point3d::*pff)() = &Point3d::sum;
    	cout<<(p3d.*pff)()<<endl;
    }
    
  • 相关阅读:
    JCTF 2014(Reverse)
    JCTF 2014(Misc)
    实验吧CTF题库-密码学(部分)
    第四章 Jinja2模版
    第三章 URL与视图
    flask学习导航主页
    flask调试模式
    rontab踩坑(三):crontab定时任务调度机制与系统时间/时区的不一致
    crontab踩坑(二):Unit crond.service could not be found.
    crontab踩坑(一)
  • 原文地址:https://www.cnblogs.com/hualimengyu/p/3766104.html
Copyright © 2011-2022 走看看