前言 回顧下C語言基礎知識,通過實現一個簡單小項目達到複習指針、動態記憶體、文件操作 等基本知識 ###內容 文件結構 main.c concat.h concat.c 入口文件main.c #include "concat.c" void initMemu() { printf("********* ...
這篇講一下《深度探索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,而不修改偏移量。
好了,除了存取效率之外,到此為止第三章內容基本就說完了,至於效率我就不測試了。