cpp多态

如果将基类中的某个成员函数声明为虚函数,那么其子类中与该函数具有相同原型的成员函数就也是虚函数,并且对基类中的版本形成覆盖。这时,通过指向子类对象的基类指针,或者引用子类对象的基类引用,调用虚函数,实际被执行的将是子类中的覆盖版本,而非基类中的原始版本,这种语法现象被称为多态。


虚函数覆盖的条件

  1. 只有类的成员函数才能被声明为虚函数,全局函数和类的静态成员函数都不能被声明为虚函数.
  2. 只有在基类中被冠以virtual关键字的成员函数才能作为虚函数被子类覆盖,而与子类中virtual关键字无关。
  3. 虚函数在子类中的覆盖版本必须和该函数在基类中原始版本拥有相同的函数签名.

多态的条件

多态特性除了需要在基类中声明虚函数,并在子类中提供有效的覆盖以外还必须通过指针或者引用来调用虚函数,才能表现出来。

纯虚函数,抽象类,纯抽象类

  • 纯虚函数
    • 形如virtual 返回类型 函数名 (形参表) [const] = 0;的虚函数被称为纯虚函数。纯虚函数不需要定义,表示抽象的行为。
  • 抽象类
    • 如果一个类包含了至少一个纯虚函数,那么这个类就是抽象类。抽象类不能被实例化为对象。
    • 如果子类没有覆盖其抽象基类中的全部纯虚函数,那么该子类就也是一个抽象类。类的抽象属性可以被继承。
  • 纯抽象类
    • 如果一个抽象类中除了构造和析构函数以外所有的成员函数都是纯虚函数,那么该抽象类就是一个纯抽象类,有名接口类。

虚析构函数

  1. delete一个指向子类对象的基类指针,实际被调用的仅仅是基类的析构函数。基类的析构函数只负责析构子类对象中的基类子对象,而不会调用子类的析构函数。这样在子类中动态分配的资源就会形成内存泄漏

  2. 如果将基类的析构函数声明为虚函数,那么子类的析构函数就也是一个虚函数,并且对基类的虚函数构成有效的覆盖,可以表现出多态特性。这时delete一个指向子类对象的基类指针,实际被调用的将是子类的析构函数。子类的析构函数在释放子类对象特有的动态资源之后会自动调用基类的析构函数,释放基类子对象中的动态资源。最终实现完美的资源释放,避免了内存泄漏。

  3. 一般而言,如果一个类没有分配任何动态资源,可以不为其定义析构函数,但是编译器会为其提供缺省析构函数,而缺省析构函数不是虚函数。为了防止delete指向子类对象的基类指针时产生内存泄漏的风险,即使是空的析构函数也有为基类定义的必要,仅仅是为了通过虚析构在对象销毁过程中体现出多态特性。

类中哪些函数可以虚?

函数 虚否
构造函数 不可以虚
静态成员函数 不可以虚
析构函数 可以虚
普通成员函数 可以虚
操作符函数 可以虚

results matching ""

    No results matching ""