今天有在校學生問怎麼獲取類中的成員變數的地址偏移量,這個應該是很多初學C++的人很好奇的問題。以前我在學校的時候,也有過這種需求。忘了當時是要寫什麼“奇怪的程式”了,反正需要獲取一個類的成員變數的地址偏移量。 其實這個問題很簡單,如果你瞭解C++的類對象記憶體分佈的話,這個根本不是問題。我給他舉了個例 ...
今天有在校學生問怎麼獲取類中的成員變數的地址偏移量,這個應該是很多初學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時,得到的成員變數地址就是它的偏移量。
到這裡,明白了吧!