C++对象模型:g++的实现(三)
这篇讲一下《深度探索C++对象模型》第三章最后没总结的一部分,就是类的成员变量指针。
这里所谓类的成员变量指针就是指绑定某个类的某个成员变量的指针,而不是某个对象的某个成员变量的指针,下面展现了两者的不同:
// test14.cpp #include <cstdio> struct Test { char c; short s; int i; }; int main() { Test t = {.c = 1, .s = 2, .i = 3}; int* pi = &t.i; // 这个指向对象的成员变量的指针,类型为int* int Test::* pmi = &Test::i; // 这是指向类的成员变量的指针,类型为int Test::* // 类的成员变量指针的使用: t.*pmi = 4; // 通过对象使用 printf("t.i = %d\n", t.i); Test* pt = &t; pt->*pmi = 5; // 通过指针调用 printf("t.i = %d\n", t.i); }
类的成员变量的指针表征的是该成员变量在类内的偏移量。
那如何判断一个指向类的成员变量的指针是无效还是有效?通常指针值为0是无效地址,但偏移为0是有效的呀。
在《深度探索C++对象模型》一书中谈到,为了实现上面的功能,向类的成员变量的指针通常会在其偏移量上加1,在使用时再把1减去。即有效的指向类的成员变量的指针是大于0的,这样0值就是无效的了。
那g++是怎么样实现的呢?
// test15.cpp #include <cstdio> struct Test { char c; short s; int i; }; int main() { Test t = {.c = 1, .s = 2, .i = 3}; int Test::* pi_valid = &Test::i; int Test::* pi_invalid = nullptr; }
使用gdb调试如下:
可见,g++的实现就是直接把无效的指针设置为-1,而不修改偏移量。
好了,除了存取效率之外,到此为止第三章内容基本就说完了,至于效率我就不测试了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!