在多重繼承中,處於中間層的類可能有一些用,但又不會實例化。在最終實現類中需要調用中間類的方法,同時必須保證在最終類中也實現該方法。如何做到?
說的不清晰,舉OceanBase的例子吧:
ObPhyOperator是一個純虛基類,它要求每一個子類都實現reset()方法:
[cpp] view plaincopyprint?class ObPhyOperator
{
public:
virtual void reset() = 0;
};
class ObPhyOperator
{
public:
virtual void reset() = 0;
};
ObSingleChildPhyOperator從ObPhyOperator繼承過來,是所有“Single child Operator"的父類,它有一個成員”child_op_"。一些情況下為了能夠重用operator,在set_child之前需要調用reset重置child_op_狀態為NULL:
[cpp]
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;
}
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的
[cpp]
virtual void reset() = 0; // 注意這個 "=0" !!!!
virtual void reset() = 0; // 注意這個 "=0" !!!!
保證了這一點。如果沒有“=0”,即使ObFinalOperator不實現reset()方法,語法上也不會報錯,給代碼維護帶來困難。
下面通過一個實驗來一步步學習這個技巧。
下面的代碼能夠編譯通過嗎?
[cpp]
#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;
}
#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;
}
報錯如下:
[plain]
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()
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實現呢?
[cpp]
#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;
}
#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;
}
報錯依舊:
[cpp]
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()
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方法:
[cpp]
#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;
}
#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~