用汇编的眼光看C++(之虚函数)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
虚函数是面向对象设计中的一个重要内容。它的出现使得我们只需要相同的接口函数,并可以得到不同的生成结果。但是有些朋友却知其然,不知其所以然,为什么会出现这样的结果,我们可以用一段代码说明问题。首先,我们先定义两个基本类型,一个是employee,一个是manager,看过前面一片博客的朋友应该都有点印象:
class employee
{
public:
employee() { }
~employee() {}
virtual void print() const { printf("employee!\n");}
};
class manager : public employee
{
public:
manager() {}
~manager() {}
void print() const {printf("manager!\n");}
};
class employee
{
public:
employee() { }
~employee() {}
virtual void print() const { printf("employee!\n");}
};
class manager : public employee
{
public:
manager() {}
~manager() {}
void print() const {printf("manager!\n");}
};
我们看到,和前面出现的成员函数稍微有一些不同,这里的print函数之前出现了virtual。然而正是这个virtual发挥了巨大的作用。可以毫不夸张地说,没有虚函数,基本上就没有设计模式,也就无法体现C++语言在面向对象设计中的巨大优越性。下面我们看看这个virtual是怎样发挥作用的?
76: employee p;
0040128D lea ecx,[ebp-10h]
00401290 call @ILT+45(employee::employee) (00401032)
00401295 mov dword ptr [ebp-4],0
77: manager m;
0040129C lea ecx,[ebp-14h]
0040129F call @ILT+65(manager::manager) (00401046)
004012A4 mov byte ptr [ebp-4],1
78: employee* e = &p;
004012A8 lea eax,[ebp-10h]
004012AB mov dword ptr [ebp-18h],eax
79: e->print();
004012AE mov ecx,dword ptr [ebp-18h]
004012B1 mov edx,dword ptr [ecx]
004012B3 mov esi,esp
004012B5 mov ecx,dword ptr [ebp-18h]
004012B8 call dword ptr [edx]
004012BA cmp esi,esp
004012BC call __chkesp (00408870)
80: e = &m;
004012C1 lea eax,[ebp-14h]
004012C4 mov dword ptr [ebp-18h],eax
81: e->print();
004012C7 mov ecx,dword ptr [ebp-18h]
004012CA mov edx,dword ptr [ecx]
004012CC mov esi,esp
004012CE mov ecx,dword ptr [ebp-18h]
004012D1 call dword ptr [edx]
004012D3 cmp esi,esp
004012D5 call __chkesp (00408870)
82: }
76: employee p;
0040128D lea ecx,[ebp-10h]
00401290 call @ILT+45(employee::employee) (00401032)
00401295 mov dword ptr [ebp-4],0
77: manager m;
0040129C lea ecx,[ebp-14h]
0040129F call @ILT+65(manager::manager) (00401046)
004012A4 mov byte ptr [ebp-4],1
78: employee* e = &p;
004012A8 lea eax,[ebp-10h]
004012AB mov dword ptr [ebp-18h],eax
79: e->print();
004012AE mov ecx,dword ptr [ebp-18h]
004012B1 mov edx,dword ptr [ecx]
004012B3 mov esi,esp
004012B5 mov ecx,dword ptr [ebp-18h]
004012B8 call dword ptr [edx]
004012BA cmp esi,esp
004012BC call __chkesp (00408870)
80: e = &m;
004012C1 lea eax,[ebp-14h]
004012C4 mov dword ptr [ebp-18h],eax
81: e->print();
004012C7 mov ecx,dword ptr [ebp-18h]
004012CA mov edx,dword ptr [ecx]
004012CC mov esi,esp
004012CE mov ecx,dword ptr [ebp-18h]
004012D1 call dword ptr [edx]
004012D3 cmp esi,esp
004012D5 call __chkesp (00408870)
82: }
上面是一段函数调用的代码,代码可以稍微有点长。不过没有关系,我们可以按照代码的行数一行一行地去进行说明和理解。
补充:软件开发 , C++ ,