// SimpleStack.cpp : Defines the entry point for the console application.
//

#include
"stdafx.h"

class Base
{
public
:
   
int
m_data;
   
static int
m_staticvalue;
    Base(
int
data)
    {
        m_data
=
data;
    }
   
virtual void
DoWork()
    {
    }
};

class
AnotherBase
{
public
:
   
virtual void
AnotherWork()
    {}
   
};

class DerivedClass:public Base,public
AnotherBase
{
public
:
    DerivedClass(
int
t_data):Base(t_data)
    {}

   
virtual    void
  DoWork()
    {
    }

   
virtual void
AnotherWork()
    {
    }
};

int Base::m_staticvalue=1
;

int main(int argc, char*
argv[])
{
   
    DerivedClass b(
1
);
    b.DoWork();

   
return 0
;
}


 

当程序运行后我们设置很简单的breakpoint: bp simplestack!derivedclass::dowork. 断点命中后的call stack如下:

0:000> kb
ChildEBP RetAddr  Args to Child             
0012ff20 0040102a 00daf6f2 00daf770 7ffd7000 SimpleStack!
DerivedClass::DoWork
0012ff80 004012f9 00000001 00420e80 00420dc0 SimpleStack!main+0x2a
0012ffc0 7c817077 00daf6f2 00daf770 7ffd7000 SimpleStack!mainCRTStartup+0xe9
0012fff0 00000000 00401210 00000000 78746341 kernel32!BaseProcessStart+0x23


这时,我们可以看看DerivedClass对象的内存内分布情况:

0:000> dt SimpleStack!DerivedClass 0012ff74
   +0x000 __VFN_table : 0x0040c020  //指向虚表的指针1
   +0x004 m_data           : 1
   =0040d030 Base::m_staticvalue : 1  //(类成员)
   +0x008
__VFN_table : 0x0040c01c  //指向虚表的指针2

可以看到,DerivedClass对象中包含两个指向虚表的指针,地址分别为0x0040c020 和0x0040c01c 。一个为指向override了BaseClass的方法的虚表,一个指向orverride了AnotherBase方法的虚表。

可以查看对应虚表中的方法:

0:000> dds 0x0040c01c
0040c01c  00401140 SimpleStack!DerivedClass::AnotherWork
0040c020  00401110 SimpleStack!DerivedClass::DoWork
0040c024  004010e0 SimpleStack!Base::DoWork
0040c028  004011a0 SimpleStack!AnotherBase::AnotherWork
......

通过以上分析,应该可以透析多态的本质了。

相关文章:

  • 2021-11-04
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-24
  • 2021-06-28
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-11-15
  • 2022-01-02
  • 2021-09-01
  • 2021-05-02
相关资源
相似解决方案