纯虚函数,类也有一张纯虚函数表,类似于纯虚函数,可是有什么区别呢?现在分析下

// 虚函数.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include


using namespace std;
class base
{
public:
virtual void demo_1()=0;
};
class Imp :public base
{
public:

virtual void demo_1()
{
cout<<"real demo_1\n";
}
};
int _tmain(int argc, _TCHAR* argv[])
{

base *p=new Imp();
p->demo_1();
base* buf=new Imp();
buf->demo_1();
return 0;
}

以上是C++的源代码,当然,为了分析方便,我们没有释放空间,大家不要学这个

text:00401000 ; void __thiscall Imp__demo_1(Imp *this)
.text:00401000 public: virtual void __thiscall Imp::demo_1(void) proc near
.text:00401000 ; DATA XREF: .rdata:const Imp::`vftable'o
.text:00401000 this = ecx
.text:00401000 mov eax, ds:std::basic_ostream<char,std::char_traits

> std::cout
.text:00401005 push eax ; _Ostr
.text:00401006 call std::operator<<<std::char_traits

>(std::basic_ostream<char,std::char_traits

> &,char const *)
.text:0040100B pop this
.text:0040100C retn
.text:0040100C public: virtual void __thiscall Imp::demo_1(void) endp
.text:0040100C
.text:0040100C ; ---------------------------------------------------------------------------
.text:0040100D align 10h
.text:00401010
.text:00401010 ; =============== S U B R O U T I N E =======================================
.text:00401010
.text:00401010
.text:00401010 ; int __cdecl wmain(int argc, wchar_t **argv)
.text:00401010 _wmain proc near ; CODE XREF: __tmainCRTStartup+11Dp
.text:00401010
.text:00401010 argc = dword ptr 8
.text:00401010 argv = dword ptr 0Ch
.text:00401010
.text:00401010 push esi
.text:00401011 mov esi, ds:operator new(uint)
.text:00401017 push 4
.text:00401019 call esi ; operator new(uint)
.text:0040101B add esp, 4
.text:0040101E test eax, eax;为一个类的实例分配空间
.text:00401020 jz short loc_40102A;检测内存空间分配是否成功
.text:00401022 mov dword ptr [eax], offset const Imp::`vftable';虚函数表的首地址放在eax指向的内存块中
.text:00401028 jmp short loc_40102C
.text:0040102A ; ---------------------------------------------------------------------------
.text:0040102A
.text:0040102A loc_40102A: ; CODE XREF: _wmain+10j
.text:0040102A xor eax, eax;如果分配失败,执行此指令
.text:0040102C
.text:0040102C loc_40102C: ; CODE XREF: _wmain+18j
.text:0040102C mov edx, [eax];将虚函数表的首地址放在edx中
.text:0040102E mov ecx, eax;ecx中放的是存放虚函数表地址的内存的地址
.text:00401030 mov eax, [edx];虚函数表中第一个函数的地址
.text:00401032 call eax;执行虚函数表中的第一个函数
.text:00401034 push 4
.text:00401036 call esi ; operator new(uint)
.text:00401038 add esp, 4;同时为第二个类的对象分配空间
.text:0040103B pop esi
.text:0040103C test eax, eax;检测类的实例内存空间是否分配成功
.text:0040103E jz short loc_401051
.text:00401040 mov dword ptr [eax], offset const Imp::`vftable';将虚函数表首地址放在eax指向的内存中
.text:00401046 mov edx, [eax];edx中放了虚函数表中的地址
.text:00401048 mov ecx, eax;
.text:0040104A mov eax, [edx];虚函数表中的第一个函数的起始位置
.text:0040104C call eax;执行虚函数表中的第一个函数
.text:0040104E xor eax, eax
.text:00401050 retn;
同时注意这两个类指向的是同一个虚函数表
.text:00401051 ; ---------------------------------------------------------------------------
.text:00401051
.text:00401051 loc_401051: ; CODE XREF: _wmain+2Ej
.text:00401051 xor eax, eax
.text:00401053 mov edx, [eax]
.text:00401055 mov ecx, eax
.text:00401057 mov eax, [edx]
.text:00401059 call eax
.text:0040105B xor eax, eax
.text:0040105D retn
.text:0040105D _wmain endp ; sp-analysis failed