继承与多态 --- 下 --- 重载与重写、多态实现原理、纯虚函数

重写与重载

函数重载:用同一个函数名定义不同的函数,当函数名和不同的参数搭配时函数的含义不同。只在同一个类中存在。

函数重写:在子类中定义与父类中原型相同的函数,函数重写只发生在父类与子类之间。

面试题:重载和重写有什么区别?什么时候是重载,什么时候是重写?

函数重载:
必须在同一个类中进行。 重载必须发生在同一个作用域之中。
子类无法重载父类的函数,父类同名函数将被覆盖。
重载是在编译期间根据参数类型和个数决定调用函数。是在编译期间。

函数重写:
必须发生于父类与子类之间。
并且父类与子类中的函数必须有完全相同的原型。
使用virtual声明之后能够产生多态。
多态是在运行期间根据具体对象的类型决定调用函数。是在运行的时间。

重载在编译时就决定了调用段函数,而重写在运行时才能确定所调用的函数,因此重载比重写的效率更高。

子类中的函数无法重载父类中的函数。
在子类中需要使用作用域限定符来实现对父类的成员的调用: Parent : :

多态的实现原理

面试题:是否可以将类的每个成员函数都声明为虚函数?

C++中多态的实现原理
1、当类中声明虚函数时,编译器会在中生成一个虚函数表
2、虚函数表是一个存储类成员函数指针的数据结构。
3、虚函数表是由编译器自动生成与维护的。
4、virtual成员函数会被编译器放入虚函数表中。
5、存在虚函数时,每个对象中都有一个指向虚函数表的指针。

只要用到了virtual,这个类就会由一个虚函数表,这个类的每一个对象都有一个指向该虚函数表的指针。

这里写图片描述

通过虚函数表指针VPTR调用重写函数是在程序运行时进行的,因此需要通过寻址操作才能确定真正应该调用的函数。而普通成员函数是在编译时就确定了调用的函数。在效率上,虚函数的效率要低很多。

VPTR位于内存中对象存储位置的头部。

出于效率考虑,没有必要将所有成员函数都声明为虚函数。

在JAVA或C#中没有虚函数的概念,他们把所有的函数都可以看作虚函数,但是C++中有virtual关键字来决定一个函数是否为虚函数。从这方面讲,C++的效率要比JAVA的效率要高。

这里写图片描述
在子类的构造函数完成之前,VPTR指针指向的是父类的虚函数表,因此子类的构造函数调用的重写函数是父类的虚函数。

纯虚函数

面向对象中的抽象类:
1、抽象类可用于表示现实世界中的抽象概念
2、抽象类是一种只能定义类型,而不能产生对象的类
3、抽象类只能被继承并重写相关函数
4、抽象类的直接特征是纯虚函数,只声明函数,而不定义函数体。

纯虚函数是只声明函数原型,而故意不定义函数体的虚函数。

抽象类与纯虚函数:
抽象类不能用于定义对象。
抽象类只能用于定义指针引用
抽象中的纯虚函数必须被子类重写。

用法如下图所示:
这里写图片描述
Shape就是一个抽象类,area( )为纯虚函数。

小结

函数重载与函数重写不同。
多态是通过虚函数表实现的。
虚函数在效率上会受到影响。
抽象类可用于表示现实世界中的抽象概念。
抽象类是通过纯虚函数实现的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值