36項 インタフェースの継承と実装の継承とを区別しよう

インタフェースの継承と実装の継承とを区別しよう


純粋仮想関数を宣言する目的は、派生クラスに関数のインタフェースを継承させることのみ。

一般仮想関数を宣言する目的は、関数のインタフェースとデフォルトの実装を継承させること。

・非仮想関数を宣言する目的は、関数のインタフェースと強制的な実装を継承させること。



※一般仮想関数で、デフォルトの実装を継承するのは、危険な場合があります。
デフォルトの実装を分離させる時は、
1,インタフェースを純粋仮想関数で継承し、実装はprotectedな非仮想関数とする。
2,純粋仮想関数に実装を持たせる。
という2つの方法が挙げられています。

1の例は下のコードです。

class Airplane{
public:
    virtual void fly(const Airport &destination) = 0;
protected:
    void defaultFly(const Airport &destination);
};

void Airplane::defaultFly(const Airport &destination)
{
    ... //飛行機を飛ばすためのデフォルトのコード
}


class ModelA : public Airplane
{
public:
    virtual void fly(const Airport &destination)
    {
        defaultFly(destination); //デフォルトの実装を呼び出す。
    }
};

class ModelB : public Airplane
{
public:
    virtual void fly(const Airport &destination)
    {
        ... //個別の実装を書く
    }
};

2の例は下のコードです。

class Airplane{
public:
    virtual void fly(const Airport &destination) = 0;
};

void Airplane::fly(const Airport &destination)
{
    ... //飛行機を飛ばすためのデフォルトのコード
}


class ModelA : public Airplane
{
public:
    virtual void fly(const Airport &destination)
    {
        Airplane::fly(destination);//デフォルトのコードを呼び出す
    }
};

class ModelB : public Airplane
{
public:
    virtual void fly(const Airport &destination)
    {
        ... //個別の実装を書く
    }
};