class base_c ...{ public: virtual ~base_c() ...{} virtual int getkind() ...{return 0;} };
class derive: public base_c ...{ public: virtual int getkind() ...{return 1;} };
derived1.cpp:
#include "base.h "
int f1() ...{ derive* pD1=new derive(); base_c* pB=new base_c(); int nRet=pD1-> getkind()+pB-> getkind(); delete pD1; delete pB;
return nRet; }
derived2.cpp:
#include "base.h "
int f2() ...{ derive* pD2=new derive(); base_c* pB=new base_c(); int nRet=pD2-> getkind()+pB-> getkind(); delete pD2; delete pB;
return nRet; }
> nm derive1.o
00000000 W _._6base_c 00000000 W _._6derive 00000000 W __6base_c 00000000 W __6derive 00000000 ? __EXCEPTION_TABLE__ 00000000 ? __FRAME_BEGIN__ U __builtin_delete U __builtin_new U __rethrow U __rtti_si U __rtti_user 00000000 W __tf6base_c 00000000 W __tf6derive 00000008 C __ti6base_c 0000000c C __ti6derive 00000000 V __vt_6base_c 00000000 V __vt_6derive 00000000 T f1__Fv 00000000 t gcc2_compiled. 00000000 W getkind__6base_c 00000000 W getkind__6derive
> nm derive2.o
00000000 W _._6base_c 00000000 W _._6derive 00000000 W __6base_c 00000000 W __6derive 00000000 ? __EXCEPTION_TABLE__ 00000000 ? __FRAME_BEGIN__ U __builtin_delete U __builtin_new U __rethrow U __rtti_si U __rtti_user 00000000 W __tf6base_c 00000000 W __tf6derive 00000008 C __ti6base_c 0000000c C __ti6derive 00000000 V __vt_6base_c 00000000 V __vt_6derive 00000000 T f2__Fv 00000000 t gcc2_compiled. 00000000 W getkind__6base_c 00000000 W getkind__6derive
test2 base.h:
class base_c ...{ public: virtual ~base_c() ...{} virtual int getkind(); };
class derive: public base_c ...{ public: virtual int getkind(); };
base.cpp:
#include "base.h "
int base_c::getkind() ...{ return 0; }
int derive::getkind() ...{ return 1; }
> nm base.o 00000000 W _._6base_c 00000000 W _._6derive 00000000 ? __FRAME_BEGIN__ U __builtin_delete U __rtti_si U __rtti_user 00000000 W __tf6base_c 00000000 W __tf6derive 00000008 C __ti6base_c 0000000c C __ti6derive 00000000 V __vt_6base_c 00000000 V __vt_6derive 00000000 t gcc2_compiled. 00000000 T getkind__6base_c 00000010 T getkind__6derive
> nm derive1.o
00000000 W __6base_c 00000000 W __6derive 00000000 ? __EXCEPTION_TABLE__ 00000000 ? __FRAME_BEGIN__ U __builtin_delete U __builtin_new U __rethrow U __vt_6base_c U __vt_6derive 00000000 T f1__Fv 00000000 t gcc2_compiled.
> nm derive2.o
00000000 W __6base_c 00000000 W __6derive 00000000 ? __EXCEPTION_TABLE__ 00000000 ? __FRAME_BEGIN__ U __builtin_delete U __builtin_new U __rethrow U __vt_6base_c U __vt_6derive 00000000 T f2__Fv 00000000 t gcc2_compiled. --------------------------------------------------------------------------------------------------------------------------------
虚函数表一般是类的第一个成员。 ------------------------------- 第一个成员是指向它的指针,就这个case而言它实现方式由编译器决定没错,我的问题是通过上门的符号表信息如何看出符号表最终插在哪个目标文件下?我的complier:gcc, g++ - GNU project C and C++ Compiler (gcc-2.96)
OOPhaisky(异化$渴望成功~~) ( ) 信誉:100 Blog 2007-01-18 22:10:54 得分: 0
虚函数表放的位置由具体的实现决定,只有一点是确定的,那就是vtable只能有一份,而不能有多份。 -------------------------------------------- 我猜符号表里__vt_6base_c这个应该是虚函数表,所以test2的结果很明显 00000000 V __vt_6base_c in base.o U __vt_6base_c in derived1.o U __vt_6base_c in derived2.o 说明在derived*.o中虚函数表无定义,但为什么在base.o中是weak symbol? 按我的原来的理解难道它不是在base.o中吗? 为什么在test1种两个derived*.o中都是V?
我想早期的编译器是先生成虚函数表,连接的时候消除重复或不消除都可以。 看到那些符号都是weak symbol,我猜是不是为了避免连接时消除重复,现在编译器在编译的时候先不生成虚函数表和其他要消除重复的符号,在连接的时候再生成。但最终连接好的可执行文件中仍然是 weak symbol,不知道怎么解释这个。 我用的是gcc, g++ - GNU project C and C++ Compiler (gcc-2.96)