今天有在校學生問怎麼獲取類中的成員變量的地址偏移量,這個應該是很多初學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時,得到的成員變量地址就是它的偏移量。
到這裡,明白了吧!