有没有一种方法可以控制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() { };
};
结果:
[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使用),但我希望它能够正常工作首先。还是完全有可能?
您甚至可以使用不同的编译器在模块之间使用C ++接口,但是您刚刚遇到了麻烦。这就是为什么接口可以在不同的编译器上工作的原因:可用的C ++编译器必须生成与COM接口一起使用的代码。COM对象看起来很像具有单个vtable的C ++对象,其指针位于该对象的偏移量为零。问题是,据我所知,COM并未为重载方法定义任何规则,但是只要您不想利用方法重载以及其他某些外来语言功能,那么您就可以信任方法顺序(因为COM兼容性)。
即使您在模块之间不使用C ++接口,模块之间的接口也应该相当简单。我从不迫切需要模块之间的接口中的方法重载。即使您需要重载,也可以为方法指定单独的名称,就像根本没有重载的语言一样。在模块之间传递基本类型和简单的数据结构也是明智的,如果仅传递基本类型,则使用不同的配置(例如Debug中的一个和Release中的其他)编译模块非常容易,以加快调试迭代的速度。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句