虚函数多态

一、知识点
1、一个操作随着所传递的对象类型的不同能够做出不同的反应,其行为模式成为多态。(P413)
 
2、基类与派生类的同名操作,只要标记上virtual,则该操作便具有多态性。(P416)
 
3、一旦标记基类的函数为虚函数,便有连锁反应,后面继承的类中一切同名成员函数都变成了虚函数。如果是引发实际复制动作的传递,则子类对象完全变成基类对象了,这时候,便不会再有悬念了,即不会有多态了。因为在参数传递的过程中已经将对象的性质做了肯定的转变。而对于确定的对象,是没有选择操作可言的。因此说白了,就是仅仅对于对象的指针和引用的间接访问,才会发生多态现象。(P417)
 
4、虚函数机理:
(1)、通过预先设定其成员函数的虚函数性质,使得任何捆绑该成员函数的未定类型的对象操作在编译时,都以一个不确定的指针特殊地“引命待发”来编码,到了运行时,遇到确定类型的对象,才突然指定其真正的行为。即滞后到运行时,根据具体类型的对象来捆绑成员函数。
(2)、多态性实现的原理
当将函数声明为virtual时,编译器在编译的时候,发现类中有虚函数,此时编译器会为每个包含虚函数的类创建一个虚表,该表是一个一维数组,在这个数组中存放着每个虚函数的地址。那么如何确定虚表呢?编译器还为每个类的对象提供了一个虚表指针,这个指针指向了对象所属类的虚表。在程序运行时,根据对象的类型去初始化虚指针,从而让虚指针正确的指向所属类的虚表,从而在调用虚函数时,能够找到正确的函数。
在构造函数总,进行了虚表的创建和虚表指针的初始化。在构造子类对象时,要先调用父类的构造函数,此时编译器只“看到了”父类,并不知道后面是否还有继承者,它初始化父类对象的虚表指针,该虚表指针指向父类的虚表。执行子类的构造函数时,子类对象的虚表指针被初始化,指向自身的虚表。
对于虚函数调用来说,每个对象内部都有一个虚表指针,该虚表指针被初始化为本类的虚表。所以在程序中,不管你的对象类型如何转换,但该对象内部的虚表指针是固定的,所以才能实现动态的对象函数调用,这就是C++多态性实现的原理。
 
(5)、总结(基类有虚函数):
a、每一个类都有虚表。
b、虚表可以继承,如果子类没有重写虚函数,那么子类虚表中仍然会有该函数的地址,只不过这个地址指向的是基类的虚函数实现。如果基类3个虚函数,那么基类的虚表中就有三项(虚函数地址),派生类也会有虚表,至少有三项,如果重写了相应的虚函数,那么虚表中的地址就会改变,指向自身的虚函数实现。如果派生类有自己的虚函数,那么虚表中就会添加该项。
c、派生类的虚表中虚函数地址的排列顺序和基类的虚表中虚函数地址排列顺序相同。
 
6、编译器看见虚函数调用,就要做滞后处理。由于间接访问比直接访问绕了一个弯,于是付出了时间代价和保存若干指针地址的空间代价。为了在使用类的编程中随时随地体现多态性,只要是继承结构,应尽量将成员函数设计成虚函数
 
7、虚函数在继承层次结构中总是会自动地从基类传播下去的。因此派生类中重载的虚函数的virtual可以省略。
 
8、虚函数用于继承结构层次中的基类与子类。除了基类与子类的函数名必须相同外,连参数类型、个数和顺序都要相同。


 

 
13、写开禁操作可以去掉常量或者常对象的常量性:(P441)
char *p = const_cast<char *>(max("hello", "world"));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值