使用するのは、Baseクラスにどんなロジックを実装したらいいのかわからないような時。
Concreteクラスには、必ずロジックを実装する必要がある。
Derivedは、必ずBaseクラスをoverrideすること。そうでないとderivedクラスもabstractになってしまう。
virtual void function() = 0;
とすることでpure virtual functionが作れる。
これが最低ひとつあると、クラスをabstractにすることができる。
pure virtual functionの中には一般的にはロジックを実装しない。
また、下記のコード例のように、abstract classとした lick
クラスをポイントするオブジェクトを生成しようとするとエラーになる。
#include <iostream> #include <vector> class lick { private: public: virtual void peron() = 0; //pure virtual function virtual void chupa() = 0; //pure virtual function virtual ~lick() {} }; class s_lick: public lick { //abstract class public: virtual ~s_lick() {} }; class m_lick: public lick { //abstract class public: virtual ~m_lick() {} }; class suck: public s_lick { //concrete class public: virtual void peron() override{ std::cout << "I suck it, peronperon" << std::endl; } virtual void chupa() override{ std::cout << "I suck it, chupachupa" << std::endl; } virtual ~suck() {} }; class taste: public m_lick { //concrete class public: virtual void peron() override{ std::cout << "I taste it, peronperon" << std::endl; } virtual void chupa() override{ std::cout << "I taste it, chupachupa" << std::endl; } virtual ~taste() {} }; int main() { // lick l; //error: variable type 'lick' is an abstract class // l.peron(); //error: variable type 'lick' is an abstract class suck s; s.peron(); s.chupa(); taste t; t.peron(); t.chupa(); lick *ptr1 = new suck(); ptr1->peron(); ptr1->chupa(); lick *ptr2 = new taste(); ptr2->peron(); ptr2->chupa(); std::vector <lick*> vec {ptr1, ptr2}; for (const auto v: vec){ v->peron(); v->chupa(); } delete ptr1; delete ptr2; }
実行結果
I suck it, peronperon I suck it, chupachupa I taste it, peronperon I taste it, chupachupa I suck it, peronperon I suck it, chupachupa I taste it, peronperon I taste it, chupachupa I suck it, peronperon I suck it, chupachupa I taste it, peronperon I taste it, chupachupa