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 = %dn", t.i);

    Test* pt = &t;
    pt->*pmi = 5;       // 通过指针调用
    printf("t.i = %dn", 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,而不修改偏移量。
好了,除了存取效率之外,到此为止第三章内容基本就说完了,至于效率我就不测试了。

原文链接: https://www.cnblogs.com/lycpp/p/16834180.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++对象模型:g++的实现(三)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/5307

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月4日 下午7:29
下一篇 2023年2月4日 下午7:30

相关推荐