关于网友提出的“ 请教关于虚表与接口的问题”问题疑问,本网通过在网上对“ 请教关于虚表与接口的问题”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:
问题: 请教关于虚表与接口的问题
描述: class IUnKown
{
public:
virtual void add(){}
virtual void release(){}
void test(){}
};
class IUnKown2
{
public:
virtual void add2(){}
virtual void release2(){}
virtual void test2(){}
};
class testIunkown : public IUnKown
{
public:
virtual void add(){}
virtual void release(){}
};
class TestInterface : public testIunkown, public IUnKown2
{
public:
virtual void add(){}
virtual void release(){}
virtual void add2(){}
virtual void release2(){}
virtual void test2(){}
};
int main(int argc, char* argv[])
{
TestInterface* ptest = new TestInterface;//1
IUnKown2 *p = (IUnKown2 *)ptest;//2
((IUnKown2*)p)->test2();//3
delete ptest;//4
return 0;//5
}
vc6下运行,通过
反汇编看第3句
43: IUnKown2 *p = (IUnKown2 *)ptest;
0040111E cmp dword ptr [ebp-10h],0
00401122 je main+7Fh (0040112f)
00401124 mov edx,dword ptr [ebp-10h]
00401127 add edx,4
0040112A mov dword ptr [ebp-28h],edx
0040112D jmp main+86h (00401136)
0040112F mov dword ptr [ebp-28h],0//这两
00401136 mov eax,dword ptr [ebp-28h]//句
00401139 mov dword ptr [ebp-14h],eax
以下两句我很奇怪,0给了这个地址,为什么下一句又把内容给eax,这时eax应该是指向IUnKown2的vptr的,而且看寄存器结果也是对的,不应该是0吗?
0040112F mov dword ptr [ebp-28h],0
00401136 mov eax,dword ptr [ebp-28h]
如果我程序是这样写
int main(int argc, char* argv[])
{
TestInterface* ptest = new TestInterface;
void *p = (void *)ptest;
((IUnKown2*)p)->test2();
((IUnKown*)p)->release();
delete ptest;
return 0;
}
查看反汇编
49: ((IUnKown2*)p)->test2();
00401124 mov eax,dword ptr [ebp-14h]
00401127 mov edx,dword ptr [eax]
00401129 mov esi,esp
0040112B mov ecx,dword ptr [ebp-14h]
0040112E call dword ptr [edx+8]
50: ((IUnKown*)p)->release();
0040EE28 mov eax,dword ptr [ebp-14h]
0040EE2B mov edx,dword ptr [eax]
0040EE2D mov esi,esp
0040EE2F mov ecx,dword ptr [ebp-14h]
0040EE32 call dword ptr [edx+4]
多继承应该比单继承多n-1年虚表,理论上这理应该有2个虚表,
这里应该象这个
第一个虚表指向-------->
virtual void add{}
virtual void release(){}
第二个虚表指向-------->
virtual void add2(){}
virtual void release2(){}
virtual void test2(){}
但看汇编的意思是,这里只有一个虚表,这两句说明
0040112E call dword ptr [edx+8] //test2
0040EE32 call dword ptr [edx+4] //release()
虚表指向-------->
virtual void add{}
virtual void release(){}
virtual void test2(){}
这是debug模式,就算是用编译器优化也不应该这样做啊,不是太明白,看c++对象模型说sun有对虚函数做了优化只用一个虚表,就算用micro用这种方法也应该有运行时重新算虚表的语句啊,谁能给我解一个,分不多,别介意:)
解决方案1: 我觉得你这段汇编没有看懂
IUnKown2 *p = (IUnKown2 *)ptest;
0040111E cmp dword ptr [ebp-10h],0
00401122 je main+7Fh (0040112f)
00401124 mov edx,dword ptr [ebp-10h]
00401127 add edx,4
0040112A mov dword ptr [ebp-28h],edx
0040112D jmp main+86h (00401136)
0040112F mov dword ptr [ebp-28h],0//这两
00401136 mov eax,dword ptr [ebp-28h]//句
00401139 mov dword ptr [ebp-14h],eax
以上介绍了“ 请教关于虚表与接口的问题”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/3674704.html