当前位置:首页 > 经验 >

动态多态是如何实现的(动态多态是通过虚表实现的嘛)

来源:原点资讯(www.yd166.com)时间:2024-03-15 20:18:19作者:YD166手机阅读>>

为了叙述简便,在本文中,将动态多态性一律简化为多态性。

在前面的文章中,我们已经简要介绍了C 的多态性,也介绍了C 的虚函数表,下面,我们来看看C 是如何利用虚函数机制来实现多态性的。(题外话:实现多态性并不一定需要用到虚函数机制)。下面,我们还是从程序的角度来看,为了便于热身,我们来看一个极为简单的程序:

#include <iostream>

using namespace std;


class E

{

public:


virtual void f()

{

cout << "E::f" << endl;

};


virtual void g()

{

cout << "E::g" << endl;

};

};


class M : public E

{

public:

virtual void g()

{

cout << "M::g" << endl;

};

};


int main()

{

E e;

M m;


E *p = &e;

p->f(); // E::f

p->g(); // E::g


p = &m;

p->f(); // E::f

p->g(); // M::g


return 0;

}

为什么同样是调用p->g();这个语句,得到了截然不同的结果呢?因为多态嘛!那这种多态性是如何实现的呢?废话不多说,直接上代码:

#include <iostream>

using namespace std;


class E

{

public:


// 为了方便叙述,故把公开a和b, 在实际系统中,很少这样做

int a;

int b;


virtual void f()

{

cout << "E::f" << endl;

};


virtual void g()

{

cout << "E::g" << endl;

};

};


class M : public E

{

public:


int c;

virtual void g()

{

cout << "M::g" << endl;

};

};


int main()

{

E e;

e.a = 1;

e.b = 2;

cout << &e << endl; // e的VTABLE的地址: 0012FF74

cout << (int *)&e << endl; // eVPTR的地址: 0012FF74

cout << &e.a << endl; // e.a的地址: 0012FF78

cout << &e.b << endl; // e.b的地址: 0012FF7C


cout << (void *)*((int *)&e) << endl; // eVPTR的值 0046F028

cout << *((int *)&e 1) << endl; // e.a的值: 1

cout << *((int *)&e 2) << endl; // e.b的值: 2


cout << (void *)*(int *)(*(int *)&e) << endl; // E的f函数的地址: 0040128F

cout << (void *)*((int *)(*(int *)&e) 1) << endl; // E的g函数的地址: 004011BD


cout << "---------" << endl;


M m;

m.a = 3;

m.b = 4;

m.c = 5;

cout << &m << endl; // m的VTABLE的地址: 0012FF64

cout << (int *)&m << endl; // mVPTR的地址: 0012FF64

cout << &m.a << endl; // m.a的地址: 0012FF68

cout << &m.b << endl; // m.b的地址: 0012FF6C

cout << &m.c << endl; // m.c的地址: 0012FF70


cout << (void *)*((int *)&m) << endl; // mVPTR的值 0046F034

cout << *((int *)&m 1) << endl; // m.a的值: 3

cout << *((int *)&m 2) << endl; // m.b的值: 4

cout << *((int *)&m 3) << endl; // m.c的值: 5


cout << (void *)*(int *)(*(int *)&m) << endl; // E的f函数的地址: 0040128F

cout << (void *)*((int *)(*(int *)&m) 1) << endl; // M的g函数的地址: 004011A8


E *p = &e;

p->f(); // E::f

p->g(); // E::g


E *q = &m;

q->f(); // E::f

q->g(); // M::g


return 0;

}

为了理解上面的程序和结果,我来画一幅图,大家就能大致明白,图如下:

动态多态是如何实现的,动态多态是通过虚表实现的嘛(1)

为了配合理解上图,下面随即给出调试程序的结果图:

动态多态是如何实现的,动态多态是通过虚表实现的嘛(2)

动态多态是如何实现的,动态多态是通过虚表实现的嘛(3)

现在应该清楚了用虚函数实现多态性的原理了吧!OK,最后感叹一句:Everything should be made as simple as possible.

最后,如果你想学C/C 可以私信小编“01”获取素材资料以及开发工具和听课权限哦!

,

栏目热文

多态的实现方式有四种(多态的使用方法和步骤)

多态的实现方式有四种(多态的使用方法和步骤)

这是面试过程中常常被问到的,那么今天我们就来从一个完全不懂得的状态到一步步了解什么是多态,来深入掌握多态的概念。什么是多...

2024-03-15 20:14:41查看全文 >>

多态最简单理解(多态的概念及实现)

多态最简单理解(多态的概念及实现)

多态定义: 指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就...

2024-03-15 20:55:17查看全文 >>

什么是多态实现多态的必要条件(多态存在的三个必要条件)

什么是多态实现多态的必要条件(多态存在的三个必要条件)

我们参加Java培训学习都是希望能够毕业后找到满意的工作,然而培训机构只是推荐就业,我们仍然需要进行面试,提高面试技术问...

2024-03-15 20:34:41查看全文 >>

多态的缺点及解决方法

多态的缺点及解决方法

什么是多态多态是面向对象的特性之一,从字面上理解,多态就是指一个对象在运行是会有多种形态,就比如可以说student是一...

2024-03-15 20:58:49查看全文 >>

多态的三种实现方式(实现多态满足哪两个条件)

多态的三种实现方式(实现多态满足哪两个条件)

虚函数和多态01 虚函数virtual virtual class Base { virtual int Fu...

2024-03-15 20:46:46查看全文 >>

实现多态的三个必要条件是什么(实现多态有哪两个要素)

实现多态的三个必要条件是什么(实现多态有哪两个要素)

前言我们知道,面向对象有三大特征:封装、继承和多态。现在我们已经了解了封装和继承,接下来在本文中,会给大家讲解多态的内容...

2024-03-15 20:43:40查看全文 >>

动态多态由什么实现(多态实现的三个条件)

动态多态由什么实现(多态实现的三个条件)

Java多态的实现机制是父类或接口定义的引用变量可以指向子类或实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是...

2024-03-15 20:10:30查看全文 >>

多态有哪些缺点和优点(多态通俗易懂的理解)

多态有哪些缺点和优点(多态通俗易懂的理解)

简单学java:优点:提高了程序的扩展性具体体现(定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型...

2024-03-15 20:14:46查看全文 >>

玥和什么字搭配最佳(玥字与什么字搭配起名好听女)

玥和什么字搭配最佳(玥字与什么字搭配起名好听女)

和玥有关的名字复玥复玥是英文 fuyeor 的音译,寓意美好。同音字:乐 月 栎 樾 嬳 哾 栎 瀹 乐 擽同部首:王 ...

2024-03-15 20:34:25查看全文 >>

玥字与什么字搭配(玥字取名和哪些字搭配)

玥字与什么字搭配(玥字取名和哪些字搭配)

龙喜神珠,吸取日月之精华玥字,五行:土 ,神珠意指光彩照人,玄妙神奇,坚毅,独特。 、指古代传说中的一种神珠。用作人名意...

2024-03-15 20:28:54查看全文 >>

文档排行