指向类成员的指针

在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 是不允许的。由于这种指针变量并不是类的成员,所以使用它只能访问对象的公有数据成员。若要访问对象的私有数据成员,必须通过成员函数来实现。

实例如下:

[cpp] view plaincopyprint?
  1. #include <iostream>
  2. using namespace std;
  3. class Point3d
  4. {
  5. public:
  6. Point3d(){x = y = z = -1;}
  7. float sum(){return x+y+z;}
  8. public:
  9. float x,y,z;
  10. static float s;
  11. };
  12. float Point3d::s = 100;
  13. int main () {
  14. cout<<Point3d::s<<endl;
  15. Point3d p3d;
  16. float Point3d::*pfm = &Point3d::x;
  17. cout<<p3d.*pfm<<endl;
  18. float *pfsm = &Point3d::s;
  19. cout<<*pfsm<<endl;
  20. float (Point3d::*pff)() = &Point3d::sum;
  21. cout<<(p3d.*pff)()<<endl;
  22. }
#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;
}

转载于:https://www.cnblogs.com/hualimengyu/p/3766104.html

指向类的数据成员和函数指针相关推荐

  1. 静态数据成员友元函数

    静态数据成员 1. static成员必须在类外定义并初始化 2. static数据成员和函数成员可以通过对象 名引用也可以通过类名引用{Clock c1,c2; c1.count; Clock::co ...

  2. 已知p是一个指向类a的数据成员m的指针_第三十八章、结构体指针、单向链表简介...

    最近比较忙,一下子有好几天没更新了,今天我们先来了解下结构体指针. 和普通的指针一样,结构体指针就是指向结构体变量的指针. 结构体指针指向的是结构体变量的起始位置. 1. 声明结构体指针 我们用一幅图 ...

  3. static关键字 void和void指针 函数指针

    static关键字 1.作用于变量:    用static声明局部变量-------局部变量指在代码块{}内部定义的变量,只在代码块内部有效(作用域),其缺省的存储方式是自动变量或说是动态存储的,即指 ...

  4. C++学习(五) 静态数据成员和静态成员函数

    文章目录 1.静态成员: 1.1.说明 1.2.格式 2.静态成员函数 2.1.说明 2.2.格式 1.静态成员: 1.1.说明 静态成员包括静态数据和静态成员函数. (1).静态数据成员的定义与普通 ...

  5. 设计一个程序,求正方形和长方形的周长,具体要求如下: (1) 定义正方形类Square作为基类,包含数据成员边长,以及构造函数、求正方形周长的虚函数、输出函数。 (2) 定义类Square的共有派

    设计一个程序,求正方形和长方形的周长,具体要求如下: (1) 定义正方形类Square作为基类,包含数据成员边长,以及构造函数.求正方形周长的虚函数.输出函数. (2) 定义类Square的共有派生类 ...

  6. C++类的静态数据成员和静态成员函数

    目录 公有属性 静态数据成员 静态成员函数 公有属性 一些类对象可能会具有一些相同的属性,如果用普通数据成员来描述这些相同的属性,这意味着我们需要给每个对象的这个数据成员设定相同的值,如果改变类对象相 ...

  7. __thiscall 转 __cdecl 时的问题,关于函数指针

    此段是xzp7772009本人所写: 在 类的成员函数 中, 有一个成员函数A 需要调用 该类中另一个 成员函数B,而成员函数中需要的是 B作为函数指针传入参数, 此情形如果处理不当,就会报类似于如下 ...

  8. 木老师教笨笨课堂——系列讲座(从函数指针到委托) 三、C++语言里的函数指针...

    先来回顾一下,我们说函数指针有一个重要的特性,它可以指向任何形参相同的函数.这样可以用统一的方式去调用不同的函数.(这个我还是希望笨笨同学好好思考一下,我想也是程序思想的精髓之一吧),就好比武功秘籍中 ...

  9. 万字长文系统梳理C++函数指针

    本篇的内容相对比较简单 主要从语法的层面讲解函数指针的使用以及应用场景.都是些面向入门者的基础,大佬轻喷. 首先:什么是函数指针. 这个问题老生常谈了,不用理解的多么复杂,它其实就是一个特殊的指针,它 ...

最新文章

  1. android 避内存溢出,Android避免内存溢出(Out of Memory)方法总结
  2. 方法论:写好一份产品需求的系统化思考模型
  3. JSP基础之 C标签中的 varStatues属性
  4. Fast marching on 3D meshes with diffusion distance
  5. 大数据分析的流程是怎样
  6. 学习英语,先记下留着后用
  7. mysql 如何避免间隙锁_mysql 间隙锁
  8. 怎么使计算机桌面整洁,如何管理电脑桌面,让桌面清洁,干净,大气......
  9. AndroidManifest.xml 最全详解(转载)
  10. java判断标签闭合_html转PDF(java)非常奇怪的错误,标签没闭合
  11. rufus中gpt和mrb磁盘_系统重装,硬盘分区MBR和GPT选哪个好?看完才知原来有这讲究!...
  12. Semi-Supervised Segmentation of Radiation-Induced Pulmonary Fibrosis from Lung CT Scans with MSGDA
  13. 风控中所涉及的重要指标全解析
  14. 【第1398期】一文读懂前端缓存
  15. 邮政快递单号可以批量查询吗
  16. “莫装B,装B遭雷劈”的英语翻译竞赛
  17. 很多人都有这个疑问:仰卧起坐真的能够减肚子么?
  18. 处理医疗影像的Python利器:PyDicom
  19. 安川伺服调试软件及说明书
  20. 【淘宝ERP】泛型Dictionary的用法详解

热门文章

  1. 叉积 微分 恒等式_考研真题分章解析 | 第二章 导数与微分
  2. python续行_python中如何优雅续行和换行
  3. 同一目录下有大量文件会影响效率吗_到底是什么原因才导致 select * 效率低下的?
  4. python tkinter怎么读_Tkinter GUI与阅读系列
  5. brew mysql 无法启动_MAC OSX brew 升级 mysql5.6到5.7无法启动的问题
  6. pdfstamper生成pdf无法显示汉字_正点原子STM32F4/F7水星开发板资料连载第四十六章 汉字显示实验...
  7. jquery导入数据_Web技术——简单的数据库编程
  8. 嵌入式开发中,用C++真香!
  9. linux 将远程mysql复制,在线备份MySQL及远程copy到远程备份服务器shell脚本
  10. python+html语音人物交互_使用Python读取HTML表并与之交互