明らかに、クラス間の関係によって異なります。言い換えれば、それは設計または実装の選択です(つまり、あなたがそれを賢明に正当化できる限り、あなた次第です)。技術的には、クラスが仮想、純粋仮想、非仮想、および静的メンバー関数を混在させることを妨げるものは何もありません。
2つの派生クラスが継承された仮想関数をオーバーライドし、同じ方法で実装する場合、 - はい - 私は真剣にその関数をベースクラスに提供することを検討します。しかし、派生したすべてのクラスがその関数の実装にデフォルトすることが理にかなっているかどうかなど、私が尋ねる疑問がたくさんあります。コードの再利用の観点からは、そのようなことは意味をなさないかもしれません。デザインの観点からは、そうではないかもしれません。
つまり、関数の特定の実装を「デフォルト」として扱うことが理にかなっているとします(つまり、その関数をオーバーライドしない限り、すべての派生クラスはデフォルトで使用されます)。基本クラス。あなたが意味をなさない示唆、両方の派生クラスが同じManoeuvre()
の機能を持っていたこと、なぜなら私達のモデリングの忠実度、この
class Aircraft
{
public:
virtual void Manoeuvre() = 0;
};
class Hornet : public Aircraft // F/A-18 hornet fighter aircraft
{
public:
void Manoeuvre();
};
class Tomcat : public Aircraft // F-14 tomcat fighter aircraft
{
public:
void Manoeuvre();
};
だがそれを言ってみましょう考えるの粗例として
- 彼らは、両方とも超音速戦闘機である(おそらく、異なるパラメータ設定であっても、同様の操縦様式を採用するだろう)。しかし、それはこの場合には、そのような
class Hercules : public Aircraft // C-130 hercules cargo plan
{
public:
void Manoeuvre();
};
として超音速戦闘機、されない航空機があるのでHercules
が操縦を継承するために、それは意味がありません、基底クラスへのManoeuvre()
機能を移動するのに十分ではありません超音速戦闘機の能力、またはその逆。したがって、これがAircraft
クラスによって供給されることは意味をなさない。この場合
、Iは中間体(Hornet
とTomcat
はなくHercules
の共通ベースとすることができる)ようFighter
などのクラス、および導入考慮するかもしれない - おそらくCargoPlane
- Iは、貨物航空機の複数のタイプを表すように求められた場合それらの共通基盤となること。その後、Fighter
とCargoPlane
の両方がAircraft
から派生する可能性がありますが、Aircraft
は、一部の機種にのみ意味をなさない機能を提供していません。
偶然のコメント:何人かの人々は別のことを主張しますが、純粋な仮想関数が定義(実装)するのを妨げるものはC++には何もありません。意味は、派生クラスによって関数をオーバーライドする必要がありますが、基本クラスによって提供されるデフォルト定義(派生クラスの関数で明示的に呼び出すことができます)があります。
なぜ基本クラスは純粋仮想メソッドしか持つことができないと思いますか? –
はい、それはまったく問題ありません。あなたがそれをインスタンス化することができないので、それが1つ以上の純粋な仮想を含んでいる限り、それは依然として抽象基本クラスですが、一般的な機能をそこに移動することは良いことです。 –
本当にあなたのルートインターフェースを完全に純粋なものにしたいのであれば(例えば、ダイナミックなファクトリlib内の実装を完全に隠す)、純粋仮想インターフェースを継承し、共通コードを実装し、残りの純粋なものを再確認する中間BaseImplを実装することもできますバーチャル、あなたのコンクリートファイナルは*から*継承することができます。 – WhozCraig