在多重继承中,处于中间层的类可能有一些用,但又不会实例化。在最终实现类中需要调用中间类的方法,同时必须保证在最终类中也实现该方法。如何做到?
说的不清晰,举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 ObPhyOperator
class ObPhyOperator
{
public:
virtual void reset() = 0;
};
/// Middle virtual class ObSingleChildPhyOperator
class ObSingleChildPhyOperator : public ObPhyOperator
{
public:
virtual void reset() = 0;
};
void ObSingleChildPhyOperator::reset()
{
cout << "single" << endl;
}
/// ObFinalOperator
class 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 ObPhyOperator
class ObPhyOperator
{
public:
virtual void reset() = 0;
};
/// Middle virtual class ObSingleChildPhyOperator
class ObSingleChildPhyOperator : public ObPhyOperator
{
public:
virtual void reset() = 0;
};
void ObSingleChildPhyOperator::reset()
{
cout << "single" << endl;
}
/// ObFinalOperator
class ObFinalOperator: public ObSingleChildPhyOperator
{
public:
virtual void reset();
};
void ObFinalOperator::reset()
{
cout << "final" << endl;
// ObSingleChildPhyOperator::reset();
}
int main()
{
ObPhyOperator *phy = new ObFinalOperator();
return 0;
}
编译通过,bingo~