由IDA分解的虚拟功能表(VFT,也就是虚拟方法表,VMT)的开头为:

br />
 _ZTV13QSystemLocale DCD 0, _ZTI13QSystemLocale, _ZN13QSystemLocaleD2Ev+1, _ZN13QSystemLocaleD0Ev+1


在这里,我们看到c++filt_ZN13QSystemLocaleD2Ev都由_ZN13QSystemLocaleD0Ev转换为c++filt

(+1是正常的,该位选择了ARM上的正确指令集) 。

Qt源声明:

 vtable for QSystemLocale DCD 0, typeinfo for QSystemLocale, QSystemLocale::~QSystemLocale()+1, QSystemLocale::~QSystemLocale()+1


为什么有两个虚拟析构函数?

(我使用ARM,Android NDK(gcc / g ++),C ++,Qt)。

#1 楼

根据文档,第一个是基础对象析构函数,第二个是删除析构函数。

Constructors and destructors are simply special cases of <unqualified-name>, where the final <unqualified-name> of a nested name is replaced by one of the following:


  <ctor-dtor-name> ::= C1   # complete object constructor
           ::= C2   # base object constructor
           ::= C3   # complete object allocating constructor
           ::= D0   # deleting destructor
           ::= D1   # complete object destructor
           ::= D2   # base object destructor


根据ARM IHI 0041D文件,这些析构函数之间的区别如下:

This ABI requires C1 and C2 constructors to return this (instead of being void functions) so that a C3 constructor
can tail call the C1 constructor and the C1 constructor can tail call C2.
Similarly, we require D2 and D1 to return this so that D0 need not save and restore this and D1 can tail call D2 (if
there are no virtual bases). D0 is still a void function.


评论


安腾ABI与​​ARM相关吗?

– 18446744073709551615
2014年5月13日9:00

我在ARM abi文档中看到了相同的内容。这些析构函数之间的区别是还原和保留“ this”指针。我将更新答案。

– w s
2014年5月13日在9:06

@ 18446744073709551615:是的。无论平台如何,它都与许多C ++实现有关。

–伊戈尔·斯科钦斯基♦
14年5月13日在11:11

@ws:实际上,区别在于删除的析构函数除了要破坏成员之外,还必须释放该对象占用的内存。即它用于实现删除pObj;陈述。 ARM要求使用返回值约定来减少代码重复,但这不是基本C ++ ABI的要求。

–伊戈尔·斯科钦斯基♦
2014年5月13日在11:15

也是stackoverflow.com/a/6921467

–维塔利·奥西波夫(Vitaly Osipov)
2014年5月14日下午2:29