2009-06-08 54 views
5

私は、いくつかの純粋仮想関数を持つ抽象クラスを持っています。私がそこから派生したクラスの1つは、純粋仮想関数の1つを使用しません:純粋な仮想関数を「削除」する方法はありますか?

class derivative: public base 
{ 
public: 
    int somevariable; 
    void somefunction(); 
}; 

とにかく、エラー(明らかに、抽象クラスから派生し、すべての純粋仮想関数をオーバーライドしない場合、クラスは引き続き抽象クラスとみなされます)。とにかく、それは専門用語で定義される必要があるので、関数

int purevirtfunc(){return 0;} 

を定義するのは意味がありません。とにかく、抽象クラスからクラスを派生させ、抽象クラスの純粋な仮想関数を使用しないでください。

+6

方法がある場合、実装されていないメソッドの1つと呼ばれるコードでは、どのようなことが起こると思いますか? – Aardvark

答えて

40

派生クラスが基本クラスの純粋仮想関数を「使用」していない場合は、派生クラスをベースから派生させるべきではありません。いずれの場合も、設計に誤りがあり、再考する必要があります。

いいえ、PVFを削除する方法はありません。

1

純仮想関数を持つクラスから継承する場合は、それらの関数を実装する必要があります。そうしないと、派生クラスも抽象クラスであり、派生クラスのオブジェクトを作成することはできません。

+0

また、このインターフェイスから頻繁に継承する場合は、継承するヌル実装を作成してスタブアウトすることもできます。 –

9

抽象クラスから派生する目的は、外部コードが抽象クラスを使用し、すべての関数が適切に実装されていることを期待することです。メソッドを実装することができないということは、この目的を打ち破り、コードを解読不能にします。しかし、あなたが選択した場合は、例外をスローすることは自由です。

1

いいえ基本クラスの既定の実装を提供するか、派生クラスの単純な実装を指定します。

14

純仮想クラスは、あなたのコードが達成されると予想されるインターフェイスです。あなたがそのインターフェースを実装し、メソッドの1つを実装していないとどうなりますか?メソッドを実装していないことを、インターフェイスを呼び出すコードがどのように知っていますか?

あなたのオプションは以下のとおりです。

  1. あなたが(それはプライベート作ること、それは使用すべきではないことを示します)を説明した方法を実装します。
  2. デザインの変更を考慮してクラス階層を変更してください。
5

これはまったく専門用語ではありません。派生クラスが親の振る舞いのすべてを示さない場合は、親クラスから派生すべきではありません。これは主要なデザインの匂いであり、おそらくデザインのリファクタリングが必要になるでしょう。

0

これを許可することは意味をなさないでしょう。実装なしで関数を呼び出すとどうなりますか?実行時エラー(それはばかげているでしょう)?場合によってはコンパイル時エラーが発生する可能性があると主張することもできますが、正確な型がわからない場合(たとえば、派生クラスのインスタンスへのポインタを関数に渡すなど)は不可能です。

1

既に良い回答がありましたが、理論的なオブジェクト指向設計の詳細については、Liskov substitution principleをご覧ください。

0

多くの人が既に述べたように、ベースメソッドは純粋な仮想であってはいけないか、派生クラスが実際にISAベースであるかどうか再考する必要があります。

ただし、基本クラスの純粋仮想メソッドの実装を提供することは可能です。これは、派生クラスのデフォルト実装のように動作しますが、基本クラスの実装の明示を選択するために派生クラスが必要です。

あなたの問題に役立つかどうかは分かりませんが、

-1

は、あなただけの

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

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

を行うことができませんでしいいえ、ありません。このような状況が発生した場合、後半の言語での規約(正当な理由があるかもしれませんが、このメソッドを他の場所、おそらく抽象クラスに移すことができるかどうかを考慮して設計してください)では、例外を発生させ、メソッドは、一部の実装でその例外が発生する可能性があることを認識します。

関連する問題