C++对象模型:g++的实现(三)
  n7Ml4MMwml9O 2023年11月02日 37 0
C++

这篇讲一下《深度探索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调试如下:
img
可见,g++的实现就是直接把无效的指针设置为-1,而不修改偏移量。
好了,除了存取效率之外,到此为止第三章内容基本就说完了,至于效率我就不测试了。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  8Tw5Riv1mGFK   2024年05月01日   80   0   0 C++
  BYaHC1OPAeY4   2024年05月08日   58   0   0 C++
  yZdUbUDB8h5t   2024年05月05日   44   0   0 C++
  oXKBKZoQY2lx   2024年05月17日   59   0   0 C++
n7Ml4MMwml9O