我總是困惑的C的存儲器佈局++虛擬table.Here是示例代碼 我使用來研究它:C++對虛擬表虛擬descructors和類的類型信息
#include <cstdio>
#include <iostream>
using namespace std;
class Point
{
public:
Point()
{
cout<<"Point constructor"<<endl;
}
virtual void func_hs()
{
cout<<"Point::func_hs"<<endl;
printf("the address of this --func_hs:%p\n",&Point::func_hs);
}
virtual void func_zzy()
{
cout<<"Point::func_zzy"<<endl;
printf("the address of this --func_zzy:%p\n",&Point::func_zzy);
}
void printVt()
{
printf("the address of object,this:%p\nthe address of vt:%p\n",
this,(void*)*(int*)this);
}
void callVtFuncs(int num=2)
{
typedef void (*Funp)(void);
for(int i=0;i<num;i++)
{
Funp funp=(Funp)*((int*)*(int*)this+i);
printf("%p\n",((int*)*(int*)this+i));
printf("Point::callVtFuncs=>address of this fun:%p\n",funp);
if(i==2||i==3)
{
continue;
}
funp();
}
}
void printVirtualFunAddress()
{
cout<<endl<<endl;
printf("func_hs:%p\nfunc_zzy:%p\n",&Point::func_hs,&Point::func_zzy);
}
virtual ~Point()
{
cout<<"Point destructor"<<endl;
}
virtual void func_zzzy()
{
cout<<"Point::func_zzzy"<<endl;
printf("the address of this --func_zzzy:%p\n",&Point::func_zzzy);
}
protected:
float x,y,z;
};
int main(int argc, char *argv[])
{
Point point;
point.printVt();
point.callVtFuncs(5);
point.printVirtualFunAddress();
return 0;
}
我把4個虛函數的類,並打印出有解決information.Here是outout:
Point constructor
the address of object,this:0xbffff620
the address of vt:0x8048db8
0x8048db8
Point::callVtFuncs=>address of this fun:0x8048914
Point::func_hs
the address of this --func_hs:0x1
0x8048dbc
Point::callVtFuncs=>address of this fun:0x8048966
Point::func_zzy
the address of this --func_zzy:0x5
0x8048dc0
Point::callVtFuncs=>address of this fun:0x8048b0a
0x8048dc4
Point::callVtFuncs=>address of this fun:0x8048b56
0x8048dc8
Point::callVtFuncs=>address of this fun:0x8048b74
Point::func_zzzy
the address of this --func_zzzy:0x11
func_hs:0x1
func_zzy:(nil)
func_zzzy:0x5
Point destructor
,我完全不明白爲什麼最後的輸出是「funz_zzy:(無)」和'funz_zzy:0x5' 但上面的是0x5和0x11。
下面是一些調試信息:(Linux的32位)
(gdb) x/16a 0x8048da8
0x8048da8: 0xa7025 0x0 0x0 0x8048dd4 <_ZTI5Point>
0x8048db8 <_ZTV5Point+8>: 0x8048914 <Point::func_hs()> 0x8048966 <Point::func_zzy()> 0x8048b0a <Point::~Point()> 0x8048b56 <Point::~Point()>
0x8048dc8 <_ZTV5Point+24>: 0x8048b74 <Point::func_zzzy()> 0x696f5035 0x746e 0x804a248 <[email protected]@CXXABI_1.3+8>
0x8048dd8 <_ZTI5Point+4>: 0x8048dcc <_ZTS5Point> 0x3b031b01 0x80 0xf
我想不通爲什麼有兩個點::〜點()? 0x804a248處的信息代表類的類型信息?
其他的一些信息:
(gdb) x/1a 0x8048dd4
0x8048dd4 <_ZTI5Point>: 0x804a248 <[email protected]@CXXABI_1.3+8>
用途是什麼0x8048dd4?
您可以使用['-fdump級-hierarchy'] (http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html)轉儲類佈局,這可能有助於/解釋一些東西。 – DCoder 2012-08-09 08:05:15
我希望你不要在代碼中的任何位置依賴你的vtable佈局,因爲這不能跨平臺和編譯器移植。 – Damian 2012-08-09 08:39:23
沒有「C++ vtable佈局」。該標準沒有定義任何這樣的事情,甚至沒有定義vtable本身的概念。 如果你想學習說gcc-4.7 vtable佈局,這是完全沒問題,但它不一定會轉化爲其他編譯器和版本。 – 2012-08-09 09:02:07