news 2026/4/18 18:46:25

C++数据成员指针

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++数据成员指针
classData1{public:inta;charb;};

int Data1:: * aa = &Data1::a;

这行代码定义了一个指向Data1类中int类型成员变量的指针aa,并将其初始化为指向成员a

  • int Data1::*是指向Data1类中int类型数据成员的指针类型。
  • aa是指针变量的名字。
  • &Data1::a获取类成员a的“地址”(实际上是成员相对于对象起始位置的偏移量,而不是内存中的绝对地址)。

之后可以通过Data1的对象或指针来访问该成员:

Data1 obj;obj.*aa=42;// 等价于 obj.a = 42;Data1*p=&obj;p->*aa=100;// 等价于 p->a = 100;

拓展

详细解析指向数据成员的指针(Pointer to Data Member)的语法。以给出的代码为例:

intData1::*aa=&Data1::a;

1. 类型声明的语法拆解

intData1::*aa;
  • int:成员变量的类型(aint类型)。
  • Data1::*:这是核心语法,表示“指向Data1类的成员”的指针。
    其中::*是一个整体运算符,称为成员指针声明符
  • aa:变量名,即这个成员指针的名字。

可以类比普通指针:int* p;中的*表示“指向 int 的指针”;
这里的Data1::*表示“指向Data1中某个成员的指针”,而前面的int指明该成员的类型。

更完整的类型描述是:指向Data1类中int类型的数据成员的指针


2. 初始化的语法

aa=&Data1::a;
  • &Data1::a不是取普通变量的地址,而是取类成员 a的“偏移地址”。
    它返回一个“成员指针”值,这个值本质上是aData1对象中的字节偏移量(或编译器内部标识)。
  • 注意:不能写成&a,因为a不属于任何具体对象,它是类的一个成员,必须通过类名::成员名来取。

语法要点&类名::成员名产生一个指向该成员的指针。


3. 为什么需要这种指针?

普通指针指向某个具体对象的某个成员(如int* p = &obj.a;)。
而数据成员指针指向的是成员在类中的“位置”,并不绑定到某个具体对象。
它可以在不同对象上使用,实现“延迟绑定成员访问”。


4. 如何使用(解引用)

成员指针不能直接解引用,必须结合一个具体的对象或对象指针,使用两个特殊的运算符:

  • .*(点星运算符):用于对象
  • ->*(箭头星运算符):用于对象指针

示例:

Data1 obj;obj.a=10;// 通过成员指针访问obj.*aa=20;// 等价于 obj.a = 20;Data1*p=&obj;p->*aa=30;// 等价于 p->a = 30;

注意:.*->*是 C++ 中优先级较低的运算符,通常需要加括号,但赋值时优先结合规则尚可。


5. 底层概念(简化理解)

  • 成员指针的值通常不是真正的内存地址,而是偏移量(字节数)。
    比如如果Data1定义为:
    classData1{intx;// 偏移 0inta;// 偏移 4(假设 int 4 字节)};
    那么&Data1::a的值在底层可能是4
  • 执行obj.*aa时,编译器将obj的起始地址加上偏移量4,从而访问到obj.a

这种实现方式意味着:

  • 成员指针不能指向静态成员(静态成员不属于对象,没有偏移量)。
  • 成员指针之间可以比较相等性(如果指向同一个成员)。
  • 成员指针可以用于虚基类的情况,但偏移量计算会复杂。

6. 类型别名简化

复杂的类型声明可以用usingtypedef简化:

usingIntMemberOfData1=intData1::*;IntMemberOfData1 aa=&Data1::a;

7. 常见应用场景

  • 遍历对象的多个同类型成员:例如一个结构体有多个int字段,可以通过成员指针数组批量操作。
  • 实现数据绑定或属性系统:将成员指针与对象结合,延迟具体成员的访问。
  • 编写泛型代码:模板中可以使用T Class::*来表示任意类型的成员指针。

8. 与普通指针的区别总结

特性普通指针int*数据成员指针int Data1::*
指向的目标某个具体对象的成员类的某个成员的位置(偏移)
初始化&obj.anullptr&Data1::anullptr
解引用需要结合对象直接*pobj.*mpptr->*mp
占用大小通常 4 或 8 字节(地址)通常 4 或 8 字节(偏移量)
指针运算(+/-)支持不支持(偏移量不能算术运算)
可以指向静态成员吗可以(&Data1::s_a不可以

9. 完整可运行示例

#include<iostream>usingnamespacestd;classData1{public:inta;intb;Data1(intx,inty):a(x),b(y){}};intmain(){intData1::*p=&Data1::a;// 指向 aintData1::*q=&Data1::b;// 指向 bData1obj(10,20);cout<<obj.*p<<endl;// 输出 10cout<<obj.*q<<endl;// 输出 20obj.*p=100;cout<<obj.a<<endl;// 输出 100return0;}

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 18:45:14

MOOG电液伺服阀G761-3005B

MOOG G761-3005B是穆格G761系列中一款高性能两级电液伺服阀&#xff0c;采用机械反馈&#xff08;MFB&#xff09;式结构&#xff0c;适用于三通和四通节流型流量控制应用&#xff0c;在四通阀模式下具有更为优异的控制性能。该阀通过接收微弱的电气模拟信号&#xff0c;精确地…

作者头像 李华
网站建设 2026/4/18 18:44:20

G-Helper终极指南:5分钟掌握华硕笔记本性能优化技巧

G-Helper终极指南&#xff1a;5分钟掌握华硕笔记本性能优化技巧 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, Scar…

作者头像 李华
网站建设 2026/4/18 18:43:15

Mininet-WiFi深度解析:构建软件定义无线网络的5大核心技术架构

Mininet-WiFi深度解析&#xff1a;构建软件定义无线网络的5大核心技术架构 【免费下载链接】mininet-wifi Emulator for Software-Defined Wireless Networks 项目地址: https://gitcode.com/gh_mirrors/mi/mininet-wifi Mininet-WiFi作为软件定义无线网络&#xff08;S…

作者头像 李华
网站建设 2026/4/18 18:43:12

AUTOSAR实战入门:从标准文档到软件架构的探索之路

1. AUTOSAR入门&#xff1a;为什么汽车工程师都需要了解它 第一次接触AUTOSAR标准文档时&#xff0c;我完全被它的厚度吓到了——200多份规范文档&#xff0c;摞起来比字典还厚。作为在汽车电子行业摸爬滚打多年的工程师&#xff0c;我完全理解新手面对这套标准体系的困惑。但别…

作者头像 李华
网站建设 2026/4/18 18:42:42

3步突破平台壁垒:Windows上直接安装Android应用的终极方案

3步突破平台壁垒&#xff1a;Windows上直接安装Android应用的终极方案 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经遇到过这样的情况&#xff1a;手头有一…

作者头像 李华
网站建设 2026/4/18 18:39:30

老旧Mac网络重生:OpenCore Legacy Patcher的无线修复方案

老旧Mac网络重生&#xff1a;OpenCore Legacy Patcher的无线修复方案 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 当2007-2017年间的Mac设备升级到新版mac…

作者头像 李华