多重继承中的纯虚函数“妙用”

来源:互联网 发布:nginx ingress 编辑:程序博客网 时间:2024/05/18 03:33

在多重继承中,处于中间层的类可能有一些用,但又不会实例化。在最终实现类中需要调用中间类的方法,同时必须保证在最终类中也实现该方法。如何做到?

说的不清晰,举OceanBase的例子吧:

ObPhyOperator是一个纯虚基类,它要求每一个子类都实现reset()方法:

class ObPhyOperator{  public:  virtual void reset() = 0;};

ObSingleChildPhyOperator从ObPhyOperator继承过来,是所有“Single child Operator"的父类,它有一个成员”child_op_"。一些情况下为了能够重用operator,在set_child之前需要调用reset重置child_op_状态为NULL:

class ObSingleChildPhyOperator : public ObPhyOperator{  public:    int set_child(ObPhyOperator *op);    virtual void reset() = 0;  // 注意这个 "=0" !!!!  private:    ObPhyOperator *child_op_;};int ObSingleChildPhyOperator::set_child(ObPhyOperator *op){  if (NULL != child_op_)  {     TBSYS_LOG(WARN, "operator already inited!");     return OB_ERROR;  }  child_op_ = op;  return OB_SUCCESS;}void ObSingleChildPhyOperator::reset(){  child_op_ = NULL;}

ObFinalOperator继承自ObSingleChildPhyOperator,我们要求它一定有一个reset()方法,用于管理operator的内部状态,如内存、基本参数等。如何做到“一定”呢?上面ObSingleChildPhyOperator的

    virtual void reset() = 0;  // 注意这个 "=0" !!!!

保证了这一点。如果没有“=0”,即使ObFinalOperator不实现reset()方法,语法上也不会报错,给代码维护带来困难。



下面通过一个实验来一步步学习这个技巧。


下面的代码能够编译通过吗?

#include <iostream>     /* cin, cout */using namespace std;class ObPhyOperator{  public:  virtual void reset() = 0;};class ObSingleChildPhyOperator : public ObPhyOperator{  public:  virtual void reset() = 0;};class ObFinalOperator: public ObSingleChildPhyOperator{  public:};int main(){  ObPhyOperator *phy = new ObFinalOperator();  return 0;}

报错如下:

virtual_structure.cpp: In function ‘int main()’:virtual_structure.cpp:54: error: cannot allocate an object of abstract type ‘ObFinalOperator’virtual_structure.cpp:35: note:   because the following virtual functions are pure within ‘ObFinalOperator’:virtual_structure.cpp:31: note:         virtual void ObSingleChildPhyOperator::reset()

OK,为ObSingleChildPhyOperator加上reset实现呢?

#include <iostream>     /* cin, cout */using namespace std;/// Base virtual class ObPhyOperatorclass ObPhyOperator{  public:  virtual void reset() = 0;};/// Middle virtual class ObSingleChildPhyOperatorclass ObSingleChildPhyOperator : public ObPhyOperator{  public:  virtual void reset() = 0;};void ObSingleChildPhyOperator::reset(){  cout << "single" << endl;}/// ObFinalOperatorclass ObFinalOperator: public ObSingleChildPhyOperator{  public:};int main(){  ObPhyOperator *phy = new ObFinalOperator();  return 0;}

报错依旧:

virtual_structure.cpp: In function ‘int main()’:virtual_structure.cpp:52: error: cannot allocate an object of abstract type ‘ObFinalOperator’virtual_structure.cpp:35: note:   because the following virtual functions are pure within ‘ObFinalOperator’:virtual_structure.cpp:45: note:         virtual void ObSingleChildPhyOperator::reset()

看来,必须在ObFinalOperator中实现reset方法:

#include <iostream>     /* cin, cout */using namespace std;/// Base virtual class ObPhyOperatorclass ObPhyOperator{  public:  virtual void reset() = 0;};/// Middle virtual class ObSingleChildPhyOperatorclass ObSingleChildPhyOperator : public ObPhyOperator{  public:  virtual void reset() = 0;};void ObSingleChildPhyOperator::reset(){  cout << "single" << endl;}/// ObFinalOperatorclass ObFinalOperator: public ObSingleChildPhyOperator{  public:    virtual void reset();};void ObFinalOperator::reset(){  cout << "final" << endl;  // ObSingleChildPhyOperator::reset();}int main(){  ObPhyOperator *phy = new ObFinalOperator();  return 0;}

编译通过,bingo~