浅谈C++多态

来源:互联网 发布:淘宝经营理念大全 编辑:程序博客网 时间:2024/06/03 17:46
多态总结:
在了解多态之前,我们必须先了解一下对象的类型,对象的类型分为两种,一种是静态类型另外一种是动态类型,静态类型是对象声明前的类型,是编译时确定的。动态类型是目前所指的随想类型,是在运行时确定的。
具体如图所示:
下面我们开始正式了解多态
多态一词来源于古希腊语,意思是具有多种形式和形态的情况,在C++语言中多态有这更广泛的含义。
多态又分为静态多态和动态多态。
静态多态也称为早绑定一般可以理解为函数重载,就是在编译器编译期间,编译器会根据函数参数的类型(有时可能进行隐式的类型转换),判断出要调用哪个函数,如果有对应的函数就调用,否则出现编译错误。


动态多态:
在程序执行期间,判断所引用对象的实际类型,而像静态多态那样在编译期间就进行了判断,根据其实际类型调用相应的方法。动态多态一般和虚函数息息相关。
所谓虚函数就是用virtual关键字修饰的成员函数,派生类需要重新实现,编译器实现动态绑定。
下面是一个例子,建立一个厕所的对象,每个厕所都有男厕和女厕,所以在厕所对象里定义了两个方法,一个是去男厕的方法,另一个是去女厕的方法。
建一个人类的基类,每一个人都有去厕所的动作,所以建立一个去厕所的方法,但是,男生和女生去的厕所不一样,所以去厕所的方法是多态的,应把该函数定义为虚函数。把人类分为男人和女人,分别继承人类重写去厕所的方法。
代码:

看到这可能有同学就有其他的疑惑了比如,类里边的普通函数可以在类外定义,虚函数可以吗?当然虚函数可以在类外定义的,具体看代码:

可以看出的是,声明要加virtual,但是在类外定义时就不用加了。
多态到这也就差不多总结完了,那我们看看下面的程序会打印出什么。


很直接的pBase->FunTest4(0,0)编译器就告诉我们出错了,没有那么多的参数那剩下的四个呢,他们各是什么,到底是运行基类的函数还是派生类的,下面我给出运行结果。

为什么结果是这样呢?这就要说一下派生类重写虚函数的条件了,都说是虚函数了那么首先基类必须是虚函数才可能被重写,其次基类的虚函数与派生类重写函数返回类型、函数名、参数列表都必须相同(除了协变以外),派生类对虚函数重写时可以带上virtual也可以不带,当然最好带上。还有要注意的是一个函数在基类中被定义为虚函数的话,在派生类中它仍为虚函数。
还有不知道各位大大都看到了吗,我在上面代码写people类时

为什么要等于0呢,这就引入了纯虚函数。什么是纯虚函数?在成员函数的形参后面写上=0,则该成员函数就是纯虚函数、包含纯虚函数的类叫做抽象类(也叫借口类),抽象类不能实例化对象。纯虚函数在派生类中定义以后,派生类才能实例化。
虚表:
单继承时代码:
类似虚拟继承,什么是虚拟继承请参阅我前一篇对继承的总结,在内存中前四个字节存的是一个地址,如图是该函数在内存中的存储的内容

那么前四个字节里边存的地址里面存的是什么呢,让我们进去看看

这地址里面也存了一堆地址,这就是虚函数的地址,这就是虚表,派生类就是通过这些地址来调用虚函数的多继承和这个还不太一样,下面我们来谈谈多继承

所以这在内存中怎么存呢?
前四个字节存的是一个地址,这个地址就是虚表的地址,这个地址里边存的是Base1的虚函数的地址下面四个字节存的是Base1的成员函数的值,在下面四个字节是一个地址,该地址表示的空间里存着Base2的虚函数地址再下面如果Base2有成员变量就是Base2的成员变量的值,若没有,当派生类有成员变量就是派生类成员变量的值,如果派生类中有新的虚函数,那么这个虚函数就会被并入到第一个继承的虚函数表里边。
这就是我对多态的一点点见解,可能不完善,也可能有错误,如果你发现了请评论,谢谢。
0 0
原创粉丝点击