有没有办法控制 vfptr 中某些类方法的顺序?看来Visual C++ 2010至少将方法指针按照声明顺序排列,重载方法除外。下面是示例代码:
enum ENUM {
};
class CLASS {
virtual void foo1() { };
virtual CLASS& __cdecl operator<<(const ENUM x) { return *this; };
virtual void foo2() { };
virtual CLASS& __cdecl operator<<(const char* x) { return *this; };
virtual CLASS& __cdecl operator<<(int x) { return *this; };
virtual void foo3() { };
virtual void foo1(int x) { };
};
int main() {
CLASS c;
return 0;
}
上面的代码生成以下vfptr:
[0] 0x00e21091 CLASS::foo1(int) *
[1] 0x00e2100a CLASS::foo1(void) *
[2] 0x00e211ae CLASS::operator<<(int) *
[3] 0x00e21050 CLASS::operator<<(char const *) *
[4] 0x00e211db CLASS::operator<<(enum ENUM) *
[5] 0x00e2106e CLASS::foo2(void) *
[6] 0x00e21172 CLASS::foo3(void) *
因此,重载方法被分组到第一个这样的声明,然后反转。将它们分组在一起不是问题,因为我可以轻松地将它们分组在头文件中。然而,相反的顺序是一个问题,因为不同的编译器显然不会这样做,这意味着它们会调用错误的方法。这与在应用程序和 DLL 之间传递对象指针有关。
首先,我希望 MSVC 对重载方法有一个首选顺序,因此我尝试按照 MSVC 在 vfptr 中的顺序声明这些方法,但随后它又简单地反转了它们,以下是代码和结果:
class CLASS {
virtual void foo1(int x) { };
virtual void foo1() { };
virtual CLASS& operator<<(int x) { return *this; };
virtual CLASS& operator<<(const char* x) { return *this; };
virtual CLASS& operator<<(const ENUM x) { return *this; };
virtual void foo2() { };
virtual void foo3() { };
};
result:
[0] 0x0113100a CLASS::foo1(void) *
[1] 0x01131091 CLASS::foo1(int) *
[2] 0x011311db CLASS::operator<<(enum ENUM) *
[3] 0x01131050 CLASS::operator<<(char const *) *
[4] 0x011311ae CLASS::operator<<(int) *
[5] 0x0113106e CLASS::foo2(void) *
[6] 0x01131172 CLASS::foo3(void) *
我想使用方法重载,至少有一种我可以使用的技巧(知道 MSVC 将使用的顺序,使用该顺序创建新标头以便仅由 DLL 使用),但我宁愿让它正常工作首先。或者说这完全有可能吗?