-
impure virtual函数--继承接口+不强制实现
impure virtual函数可能的问题,参见下面的例子
class Airport {}; class Airplane { public: virtual void fly(const Airport& destination) { //飞机飞往指定的目的地 } }; //两种飞机 class ModelA :public Airplane {}; class ModelB :public Airplane {};
impure virtual带来的问题可能是:默认的飞行函数带来错误的动作,比如ModelB忘记override fly函数,于是用了一种错误的飞行方式(Airplane的fly函数)。
于是可以把class Airplane改为下面这样,
class Airplane { public: void fly(const Airport& destination) = 0; //保证Derived类必须自己实现 private: void defaulfly() { //默认飞行动作 } }; class ModelB :public Airplane { public: void fly(const Airport& destination) { //1. 可用默认的函数,相当于实现了impure virtual函数的继承 defalutfly(); //2. 或者实现B特定的飞行动作 // 自定义实现 } };
这样有Derived类必须实现的意思,也可以使用Base类的函数,但每次复制default函数还是很烦躁。于是有如下的写法。
-
pure virtual 函数--继承接口+强制实现
class Shape { public: virtual void draw() const = 0; virtual void error(const std::string& msg); int objectID() const; }; class Rectangle :public Shape {}; class Ellipse :public Shape {};
- 纯虚函数只是为了让derived class继承实现这个接口
- 带有pure virtual函数的类不可以被new出来,即new Shape是错误的
- 但可以通过调用derived类调用Base类的pure virtual函数
{ //Shape *ps = new Shape; //错误,不能实例化 Shape* ps1 = new Rectangle; ps1->Shape::draw(); //调用pure virtual 函数 }
#include <iostream> class Shape { public: virtual void draw() const = 0; }; void Shape::draw() const { std::cout << "base draw" << std::endl; } class Rectangle :public Shape { public: virtual void draw() const { std::cout << "Derived draw" << std::endl; } }; class Ellipse :public Shape {}; int main() { Rectangle* rec = new Rectangle; rec->draw(); rec->Shape::draw(); return 0; }
如上:把pure virtual函数draw()实现,然后Derived类也实现draw(),这样和上述的写法是一个意思,但多了一层Derived类必须继承实现的意思(pure virtual函数),
-
non-virtual函数---只继承接口
总结:一个类里面有三种函数:
pure virtual代表必须继承,强制实现。
virtual函数代表必须继承,不强制实现。
non-virtual函数代表只继承接口。