# 非纯虚函数和纯虚函数
虚函数都是非纯虚函数的类不是抽象类, 只要含有纯虚函数(注意是纯)的类就是抽象类 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.
e1which points to the derived class object with function implemention calls the function in derived function.e2which points to the derived class object without function implemention calls the function in base function.e3which 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。