4

私が基本クラスを持っている場合:

class Base {
    public:
        Base(){}
        virtual void foo()=0;
};

Base クラスから任意のクラスを派生させる場合は、オーバーライドする必要がありますfoo()

foo()Base クラスにも動作が必要な場合はどうすればよいですか? その基本クラスには独自のものfooがあり、その上に、そのすべてがオーバーライドする必要がありますfooか? それは可能ですか?

4

2 に答える 2

6

次のようなことをすると:

class Base {
    public:
        Base(){}
        virtual void foo() = 0;
};
void Base::foo() {
{ 
     cout << "Hello";
}

抽象クラスを取得するため、クラス Base のオブジェクト b を作成し、b.foo() を呼び出して foo() の実装を使用させることはできません。

だから、これはあなたが望むものではありません!次の質問は、Base::foo を使用できないのに、なぜ実装を提供することを許可されたのかということです。まあ、実際にできます!直接ではありませんが。

class Deriv : public Base {
    public:
        Deriv(){}
        virtual void foo();
};
void Deriv::foo() 
{ 
     Base::foo(); cout << "  world!";
}

ご覧のとおり、 Base::foo()は派生クラスで使用できます。

質問に戻ります。答えは、基本クラスが抽象化されることを除いて、指定したとおりに 実行できるということです。

別の方法は、Base で foo() の実装を提供するときに =0 を指定せずに、ほとんどの人が行うことを行うことです。つまり、派生クラスは foo() をオーバーライドできますが、オーバーライドする必要はありませ。これは実際には完全に理にかなっているように思えます: Base::foo() のデフォルトの実装が理にかなっている派生クラスでは、それを保持しますが、何か違うものが必要な場合はそれをオーバーライドします。

更新:質問が求めていることを実際に必要とするシナリオを考え出そうとしましたが、これを思いつきました:

Document とその派生クラスがドキュメント タイプを表し、Document には、ドキュメント タイプを表すアイコンのイメージ ファイルの URL を返す仮想メソッド getClassIcon() が含まれているとします。Document がアイコン (一般的なドキュメントを表すもの) を持つことは理にかなっており、独自のアイコンを提供するためにすべての派生クラスに getClassIcon() をオーバーライドするよう要求することも理にかなっています。

そうは言っても、この特定の例では、別の設計を見つけるのは簡単に思えます: Document::getClassIcon() を純粋な仮想メソッド (=0) にし (Document を抽象クラスにします)、派生クラスの 1 つとして OtherDocument を追加します。以前は getClassIcon Document の実装にありました。PDFDocument、MSWordDocument などはすべて、必要に応じて getClassIcon() をオーバーライドする必要があります。この再設計によって明らかになる可能性があるのは、以前の設計 (質問が求めていることを可能にする架空のバージョンの C++ によってサポートされている) では、基底クラスの役割である Document とクラス スタンディングの役割が混同されていたということです。既知のタイプである OtherDocument のいずれにも属さないドキュメントの場合。もちろん、それはすべて見る人の目にかかっています。-) 2 番目の設計は、言語に機能がないために単に必要だったと主張する人もいるかもしれません。私たちは、私たちが話す (コンピューター) 言語に従って (大部分) 考えていると思います。:-)

于 2012-11-27T21:09:30.257 に答える