一直以来的想法:虚函数在虚函数表中的顺序是按照虚函数在类中定义的先后顺序。实际上并非如此。
今天在看一个宕机dump的时候发现这个事实。
后来随便测试了下,对于没有重载函数而言,是按照虚函数在类中定义的先后顺序,但是一旦有重载虚函数,形势就变了。
gcc和vs对于这种情况的实现又不一样。这里只说vs。
vs对于有重载的虚函数,其在虚函数表中出现的顺序是倒序的。也就是说,重载虚函数越前,其在虚函数表中的位置越靠后。当然,这里还有一个组的概念,也就是说,重载的虚函数总是在一个组中,中间不会掺杂其他的虚函数,即使你重载的虚函数在类中声明的位置不连续。
此时vtbl的布局如下:
__vfptr const GS::~vftbale
[0] GS::realse(void)
[1] GS::create(std::string &)
[2] GS::create(double)
[3] GS::create(int)
[4] GS::create(void)
[5] GS::save(void)
参考:
Both Visual C++ and G++ puts functions in order of declaration into the
VTable. However, if the same name is used for several virtual functions,
there is a difference:
- G++ keeps to the order of declaration
- Visual C++ stores functions into the VTable in reversed order of
declaration.
Apparently the reason for VC++ to do this is backwards compatability
with some pre-windows X86 std. COM had to support that. No better reason
than that.
Stay away from virtual functions with the same name if you want cross
compiler operation.
Neither, it's your code that's incorrect. Overloading methods isn't
supported by COM. The MIDL compiler won't let you define an interface
with two methods that have same name. It also won't let you define a
method that takes reference type as one of it's arguments. You should
only use C types in your interface, otherwise you'll probably run into
other incompatibilites between Visual C++ and MinGW.
http://www.nabble.com/Incorrect-vtable-generation-in-MinGW--td15781052.html