多态原理实现分析及重载,隐藏,覆盖的辨析

来源:互联网 发布:ddos攻击器软件 编辑:程序博客网 时间:2024/06/06 20:27

上一篇文章我讲到关于多态的使用,我们是不是感到非常神奇,为啥就是简单的加个virtual就能访问到子类的函数。无疑C++底层帮我们做很多的工作,C++的前辈们在底层加入__vfptr这样一个虚函数表,用来存我们申明为virtual的函数。加virtual之后访问子类函数的门道就在这里,我们以一个简单的程序来讲解:
这里写图片描述
我们在父类base中申明三个函数,两个虚函数,一个普通函数。在子类D中我们重写virtual show(),
print(),还加入新成员。我们来看看__vfptr的变化。
这里写图片描述
我们可以看到b对象的__vfptr中包含它的两个虚方法;d对象中因为重写父类的virtual show方法,而__vfptr改变。但是我们却在虚表中看不到example的身影,同时细心的同学一定发现d对象的虚表是建立在它所包含的父类中的。其实是这样的,我们子类继承之后,如果改写了父类的虚函数,我们就把子类的虚函数地址覆盖原来父类中的虚函数,这样我们就可以通过父类引用或者指针访问子类函数了,如果没有改写就继续保留父类的虚函数如示例中的list函数。因为父类中并没有example这个虚函数,并不会看到example这个函数。
但是,我们的虚表中其实是有这个函数的,但是由于base的查看范围有限不会显示。
我们可以通过查看内存发现虚表中有一块地址和example的地址相同
这里写图片描述
前两个是D::show()和base::list()的地址。存万所有虚函数我们会在最后存一个0x00000000代表结束.

在这里我们也看到覆盖这个概念,我们要把它和重载,隐藏进行区分。
重载:是在同一个类里面,所有函数名相同的函数都可成为重载。
隐藏:必须是在不同类里面,不可申明为virtual,只要函数名相同,我们在子类对象就不能访问父类函数,我们就称子类的函数隐藏父类的函数。
覆盖:在不同类里,必须加virtual,函数必须达到三同。这就是我们上边所提到的虚表里的东西,如果子类重写父类的虚函数,我们就会用子类函数地址去覆盖父类函数的地址。

阅读全文
1 0
原创粉丝点击