如何解决为什么MSVC和GCC在vtable中将覆盖的纯虚拟函数放置在不同的位置?
首先,MCVE:
#include <cstdio>
class Base {
public:
virtual void Print(int x) = 0;
virtual void Print(double x) = 0;
};
class Derived : public Base {
public:
void Print(int x) override { printf("%d\n",x); }
void Print(double x) override { printf("%lf\n",x); }
};
int main(void) {
class Derived obj;
obj.Print(2);
obj.Print(3.141);
}
在上面的C ++代码中,基类具有相同功能的两个纯虚函数 名称但参数类型不同-第一个打印整数,然后第二个 一印双。具有相同的虚拟方法名称很重要,因为如果 方法名称相同,则MSVC和GCC在结果二进制文件中产生相同的效果。
正在反汇编(IDA):
- GCC 10.2.0:
g++.exe -Wall -pedantic test.cpp
.rdata:A0 ; `typeinfo name for'Base
.rdata:A0 _ZTS4Base db '4Base',0 ; type descriptor name
.rdata:A6 align 10h
.rdata:B0 public _ZTS7Derived
.rdata:B0 ; `typeinfo name for'Derived
.rdata:B0 _ZTS7Derived db '7Derived',0 ; type descriptor name
.rdata:B9 align 20h
.rdata:C0 public _ZTV7Derived
.rdata:C0 ; `vtable for'Derived
.rdata:C0 _ZTV7Derived dq 0 ; offset to this
.rdata:C8 dq offset _ZTI7Derived ; `typeinfo for'Derived
.rdata:D0 off_4098D0 dq offset _ZN7Derived5PrintEi ; Derived::Print(int)
.rdata:D8 dq offset _ZN7Derived5PrintEd ; Derived::Print(double)
- MSVC 19.26.28806:
cl.exe /Zi test.cpp
.rdata:20 dq offset ??_R4Base@@6B@ ; const Base::`RTTI Complete Object Locator'
.rdata:28 ??_7Base@@6B@ dq offset j__purecall
.rdata:30 dq offset j__purecall
.rdata:38 align 20h
.rdata:40 dq offset ??_R4Derived@@6B@ ; const Derived::`RTTI Complete Object Locator'
.rdata:48 ??_7Derived@@6B@ dq offset j_?Print@Derived@@UEAAXN@Z ; Derived::Print(double)
.rdata:50 dq offset j_?Print@Derived@@UEAAXH@Z ; Derived::Print(int)
在派生vtable中,Derived::Print(int)
和Derived::Print(double)
在GCC和MVSC生成的二进制文件之间的顺序相反。那么,为什么
vtable中由生成的二进制文件中纯虚拟方法的顺序不同
GCC和MSVC?还有为什么只有在重写方法的情况下才会发生这种情况?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。