我想了解用於實現指向非靜態成員函數的指針的底層機制。我正在尋找一個類似於vtbl(用於多態的虛擬表)在全局中工作的答案,而不用擔心從編譯器到編譯器的細節可能不同。指向非靜態成員函數的指針的值
實施例:
#include <stdio.h>
class A {
public:
int i;
int j;
void foo(void) { };
};
int main()
{
int A::*ptr_j = &A::j;
void (A::*ptr_f)(void) = &A::foo;
printf("Foo::j pointer to data member %p\r\n", ptr_j);
printf("Foo::foo pointer to function member %p\r\n", ptr_f);
}
結果是
Foo::j
指向數據成員0x4
Foo::foo
函數指針構件0x804844c
選自「C++編程語言通過Stroustrup的」,
甲指針構件...更像是一個偏移量的結構或索引到一個數組...
對於數據成員,我知道指針對成員Foo::j
或多或少等於offsetOf(Foo, j)
。在我的主機環境中使用gcc編譯器時的值爲4,它與offsetOf(Foo, j)
的值爲4.
對於函數成員,返回值爲0x804844c
。這是一些地址屬於全局數據區
所以我的問題是(其中的類加載):
什麼是「對象」,也就是地址0x804844c
。
- 它不可能是一個簡單的
offsetOf()
,因爲這是一個很大的偏移。 - 它不能是vtbl的地址(或vtbl中的條目的地址),因爲我相信vbtl是與實例化對象關聯的實體,而不是類。
- 它不能是加載函數的實現代碼的地址。因爲在應用派生對象時,同一個指針可能會呈現多態。
那麼什麼是在地址0x804844c
對象,什麼時候應用操作->*
或.*
其在翻譯的指針到成員函數到實際的函數地址的作用是?
在C++語言標準使用該術語的意義上,函數不是「對象」。請注意,成員函數通常作爲具有附加參數的常規函數來實現(該對象變成'this')。在那些實現中,它們不駐留在類實例本身中,而是與代碼段中的其他(免費)函數一起。 – dyp
*「它不能是加載函數的實現代碼的地址,因爲當應用派生對象時,同一個指針可能會呈現多態。」 [這個答案](http://stackoverflow.com/a/1087671/420683) – dyp