今天有在校學生問怎么獲取類中的成員變量的地址偏移量,這個應該是很多初學C++的人很好奇的問題。以前我在學校的時候,也有過這種需求。忘了當時是要寫什么“奇怪的程序”了,反正需要獲取一個類的成員變量的地址偏移量。
其實這個問題很簡單,如果你了解C++的類對象內存分布的話,這個根本不是問題。我給他舉了個例子:
struct A
{
int i;
};
&((A*)0)->i; // 這樣就可以獲取到偏移量了。他表示不理解,OK,我們來具體說說。
假如定義個變量A a; 我們都知道 &a表示變量a的首地址,&(a.i)表示變量i的地址,那么&(a.i)減去&a不就得到i的偏移量了嗎?
是的,就是這么簡單。那么這個例子&((A*)0)->i;有什么關系呢?
&((A*)0)的地地址就是0,所以&((A*)0)->i 等於&((A*)0)->i減去0。
那個學生更好奇了,為什么&((A*)0)->i 不會出問題?這個例子里並沒有為A的對象分配內存,那怎么可以得到它的地址呢?
是的,這里確實沒有分配內存,但是這個例子里我們並沒有要求有內存,我們也不對內存進行操作,所以不會引來崩潰。
&((A*)0)->i只是借助編譯器為我們計算出它的地址。當編譯器要用要一個成員變量的時候,它會根據對象的首地址加上成員的偏移量得到成員變量的地址。當對象的首地址為0時,得到的成員變量地址就是它的偏移量。
到這里,明白了吧!