你了解C++虚函数吗?掌握这6大方法,面试不再虚!

0.前言

在后端面试中语言特性的掌握直接决定面试成败,因此本公众号在在后续会持续输出编程语言的必知必会知识点系列。
C++语言一直在增加很多新特性来提高使用者的便利性,但是每种特性都有复杂的背后实现,充分理解实现原理和设计原因,才能更好地掌握这种新特性。
C++语言

只要出发总会达到,只有出发才会到达,焦虑没用,学就完了,今天一起来学习C++的虚函数考点吧。
通过本文你将了解的以下内容:

C++多态机制

虚函数的基本使用

虚函数的底层实现

纯虚函数和抽象类

虚析构函数

虚函数的优缺点

重要学习资料以及学习解答指导,请点击这里——立即领取**

1.C++多态机制

多态机制简介

C++面向对象的三大特征:
多态(Polymorphism)

封装(Encapsulation)

继承(Inheritance)

从字面上理解多态就是多种形态,具体如何多种形态,多态和继承的关系非常密切,试想下面的场景:
派生类继承使用基类提供的方法,不需更改

同一个方法在基类和派生类的行为是不同的,具体行为取决于调用对象。

后者就是C++的多态需求场景,即同一方法的行为随调用者上下文而异,举个现实生活中类似的栗子,来加深理解:

基类Woker包括三个方法:打卡、午休、干活。

派生类包括产品经理PMer、研发工程师RDer、测试工程师Tester,派生类从基类Worker中继承了打卡、午休、干活三个方法。

打卡和午休对三个派生类来说是一样的,因此可以直接调用基类的方法即可。

但是每个派生类中干活这个方法具体的实现并不一样:产品经理提需求、研发写代码、测试找Bug。

SomeWhere

C++语言
重要学习资料以及学习解答指导,请点击这里——立即领取**

计算机程序的出现就是为了解决现实中的问题,从上面的例子可以看到,这种同一方法的行为随调用者而异的需求很普遍,然而多态的设计原因只有C++之父Bjarne Stroustrup大佬最清楚了。
静态绑定和动态绑定

要充分理解多态,就要先说什么是绑定?

绑定体现了函数调用和函数本身代码的关联,也就是产生调用时如何找到提供调用的方法入口,这里又引申出两个概念:
静态绑定:程序编译过程中把函数调用与执行调用所需的代码相关联,这种绑定发生在编译期,程序未运行就已确定,也称为前期绑定。

动态绑定:执行期间判断所引用对象的实际类型来确定调用其相应的方法,这种发生于运行期,程序运行时才确定响应调用的方法,也称为后期绑定。

静态多态和动态多态

在C++泛型编程中可以基于模板template和重载override两种形式来实现静态多态。
动态多态主要依赖于虚函数机制来实现,不同的编译器对虚函数机制的实现也有一些差异,本文主要介绍Linux环境下gcc/g++编译器的实现方法。

多态本质上是一种泛型技术,说白了就是试图使用不变的代码来实现可变的算法,要么试图在编译时决定,要么试图在运行时决定。

虚函数与三大特征

虚函数为多态提供了基础,并且借助于继承来发挥多态的优势,从而完善了语言设计的封装,可见虚函数与C++三大特征之间有紧密的联系,是非常重要的特性。
C++语言

2.虚函数的基本使用

虚函数使用实例

使用virtual关键字即可将成员函数标记为虚函数,派生类继承基类的虚函数之后,可以重写该成员函数,派生类中是否增加virtual关键字均可,代码举例:

#include<iostream>
using namespace std;

class Worker{
   
  public:
    virtual ~Worker(){
   }
    virtual void DoMyWork(){
   
      cout<<"BaseWorker:I am base worker"<<endl;
    }
};

class PMer:public Worker{
   
  public:
    //virtual void DoMyWork(){
   
    void DoMyWork(){
   
      cout<<"ChildPMer:Tell rd demands"<<endl;
    }
};
class RDer:public Worker{
   
  public:
    //virtual void DoMyWork(){
   
    void DoMyWork(){
   
      cout<<"ChildRDer:Write code and solve bugs"<<endl;
    }
};
class Tester:public Worker{
   
  public:
    //virtual void DoMyWork(){
   
    void DoMyWork(){
   
      cout<<"ChildTester:Find bugs and inform rd"<<endl;
    }
};

int main(){
   
  //使用基类指针访问派生类
  Worker *ptr_pm = new PMer();
  Worker *ptr_rd = new RDer();
  Worker *ptr_ts = new Tester();
  cout<<"#### use ptr #####"<<endl;
  ptr_pm->DoMyWork();
  ptr_rd->DoMyWork();
  ptr_ts->DoMyWork();
  ptr_pm->Worker::DoMyWork();
  cout<<"-----------------------------"<<endl;
  //使用基类引用访问派生类
  PMer pmins;
  RDer rdins;
  Tester tsins
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值