# 非纯虚函数和纯虚函数

虚函数都是非纯虚函数的类不是抽象类, 只要含有虚函数(注意是纯)的类就是抽象类 abstract class.

非纯虚函数的类可以实例化(因为虚函数有函数体), 纯虚函数的类(抽象类)不可以实例化(因为虚函数没有函数体).

# 2.1. have body

The function in the base class have the body content. So the base class can create a object.

PS: virtual void attack(){} belongs to this type.

  • e1 which points to the derived class object with function implemention calls the function in derived function.
  • e2 which points to the derived class object without function implemention calls the function in base function.
  • e3 which points to the base class object calls the function in base function.
#include <iostream>
using namespace std;

class Enemy {
protected: 
    int attackPower = 0;
public:
    virtual void attack(){
        cout << "Enemy! - "<<attackPower<<endl;
    }
};

class Ninja: public Enemy {
public:
    void attack() {
        cout << "Ninja! - "<<attackPower<<endl;
    }
};

class Monster: public Enemy {};

int main() {
    Ninja n;
    Monster m;
    Enemy q;
    Enemy *e1 = &n;
    Enemy *e2 = &m;
    Enemy *e3 = &q;
    e1->attack();
    e2->attack();
    e3->attack();
}

# 2.2. no body 纯虚函数

This function is called pure virtual function and has the special syntax virtual void attack() = 0; (this statement is a declaration which ends with semicolon).

Every derived class inheriting an abstract class must override that function. (or compiler error)

不能用抽象类生成对象, 以下均错:

Enemy q;

Enemy q[3];

Ninja n;
Enemy q=n;

但是抽象类能作为指针或引用指向子类的对象或函数:

Ninja n;
Monster m;

// 指针
Enemy *e1 = &n;

// 引用
Enemy &e2 = m;

# 哪些虚函数

析构函数可以

静态成员函数、构造函数,不行。

# 虚析构

不是虚析构

// B继承A,都是正常写法的A(),~A(),B,~B()
A *a = new B;
delete a;

结果是A::A, B::B, A::~A

不是虚析构,因此不调用子类的析构函数。

变成虚析构

基类A的析构函数加virtual,变成虚析构,就要调用子类的析构函数。

virtual ~A(){/*...*/}

结果是A::A, B::B,B::~B, A::~A