C++基础学习(11)——虚函数

虚函数

虚函数实现多态的条件
什么是虚函数
  • 被virtual关键字修饰的成员函数就是虚函数,虚函数的作用是实现多态性——以共同的方法对不同的对象采取不同的策略
  • 虚函数只能是类中成员函数,且不能是静态的
虚函数的定义
class 类名{
    virtual 返回类型 函数名(形参表); //虚函数
}

注意:

  1. virtual只能在类体中使用,即如果成员函数的实现在类外,则只能在类体里的函数声明前加virtual修饰
  2. 当在派生类中定义了一个同名的成员函数时,只要改成员函数参数个数、参数类型以及返回类型与基类中同名函数完全一样,则派生类的这个成员函数无论是否使用virtual,它都将成员一个虚函数
  3. 程序猿习惯该派生类的同名函数也加上virtual,便于阅读和理解
  4. 利用虚函数,可在基类和派生类中使用相同的函数名定义函数的不同实现,从而实现“一个接口,多种方式”。
  5. 关键字virtual指示C++编译器在调用虚函数是进行动态联编,不过使用虚函数不一定产生多态性,也不一定使用动态联编,在调用时使用成员名限定,可以强制C++对该函数的调用使用静态联编
虚函数实现多态的条件

应同时满足以下三个条件:

  1. 类之间的继承关系满足赋值兼容性规则

  2. 改写了同名的虚函数

  3. 根据赋值兼容性规则使用指针(或引用),有两种情况

    • 使用基类指针(或引用)访问虚函数

      Point *p = new Circle;
      cout << p->area(); // 动态联编
      
    • 把指针(或引用)作为函数参数,这个函数不一定是类的成员函数,可以是普通函数,而且可以重载

      void fun(Point *p)
      {
          cout << p->area(); //动态联编
      }
      
特别地
  • 在派生类中,当一个指向基类成员函数的指针指向一个虚函数,并且通过指向对象的基类指针(或引用)访问这个虚函数时,仍将发生多态性
何时需要虚函数
  1. 首先看成员函数所在的类是否会作为基类,然后看成员函数的类在继承后有无可能被更改功能,如果希望派生类更改其功能,一般应该将它声明为虚函数
  2. 如果成员函数在类被继承后功能不需要修改,或派生类用不到该函数则不需要声明为虚函数
  3. 应考虑对成员函数的调用是通过对象名还是通过基类指针或引用去访问,如果是通过基类指针或引用去访问的,则应当声明为虚函数
类成员函数的指针与多态性
虚析构函数
为什么要有虚析构函数
  • 派生类的对象从内存中撤销时,一般先调用派生类的析构函数,然后再调用基类的析构函数,
  • 但是如果用new运算符建立了派生类对象,且定义了一个基类的指针指向这个对象,那么当用delete运算符撤销对象时,系统会只执行基类的析构函数,而不执行派生类的析构函数,因而也无法对派生类对象进行真正的撤销清理操作
  • 如果希望删除派生类对象,则需要虚析构函数
如何定义虚析构函数
Point *pp - new Circle; // 基类指针指向派生类
delete pp; // 仅执行基类析构函数
  • 如果希望“delete pp”执行Circle的析构函数,那么基类Point的析构函数要声明为虚函数,称为虚析构函数
  • 如果将基类的析构函数声明为虚函数,由该基类所派生的所有派生类的析构函数也都自动成为虚函数,即使派生类的析构函数与基类的析构函数名不相同

说明:

  1. 党基类的析构函数为虚函数时,无论指针指的是同一类族中的哪一个类对象,系统总会采用动态联编,调用正确的析构函数,对该对象进行清理
  2. C++支持虚析构函数,但不支持虚构造函数,即构造函数不能声明为虚函数
纯虚函数和抽象类
纯虚函数的定义

许多情况下,无法在基类中为虚函数给出一个有意义的定义,这时可以将它说为纯虚函数,将具体的定义留给派生类去做。纯虚函数的定义形式为:

virtual 返回类型 函数名(形参表)=0; // 即在虚函数的原型声明后加上“=0”,表示纯虚函数根本没有函数体

说明:

  1. 纯虚函数的作用是在基类中为其派生类保留一个函数的名字,以便派生类根据需要对它进行定义,如果在一个类中声明了纯虚函数,而在其派生类中没有对该函数定义,则该虚函数在派生类中仍然为纯虚函数
  2. 包含有纯虚函数的类称为抽象类。一个抽象类只能作为基类来派生新类,所有又称为抽象基类
  3. 如果在派生类中给出了抽象类的纯虚函数的实现,则该派生类不再是抽象类。否则之哟啊派生类仍然有纯虚函数,则派生类依然是抽象类。抽象类至少含有一个虚函数且至少有一个虚函数是纯虚函数。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值