这里所谓类的成员变量指针就是指绑定某个类的某个成员变量的指针,而不是某个对象的某个成员变量的指针,下面展现了两者的不同:
// 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,而不修改偏移量。
好了,除了存取效率之外,到此为止第三章内容基本就说完了,至于效率我就不测试了。
标签:c++,对象模型,函数,static,编辑,参数, 来源:
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。