2013-04-05 57 views
5

私は通常、自分のコードがうまくいくために必要なメソッドに対して純粋な仮想関数を使用します。したがって、私はインターフェイスを作成し、他のユーザーは派生クラスを実装します。派生クラスはこれらの仮想関数だけをpublicとして持っていますが、私のコードでは呼び出さないので、いくつかの追加メソッドをprivateとして実装する必要があります。 これがOOPの良い習慣と考えられるかどうかわかりません(どのデザインパターンがありますか?)。 とにかく、私の質問は次のとおりです: ユーザーが純粋な仮想関数をオーバーロードすることはできますか?基本クラスで純粋仮想関数のオーバーロード

virtual void foo(int,double,double=0)=0; 

が、それは非常に限られている:

すなわち

class Base 
{ 
public: 
Base(); 
virtual ~Base(); 
virtual void foo(int,double)=0; 
}; 

class Derived: 
public Base 
{ 
private: 
    // methods 
public: 
Derived(); 
virtual ~Derived(); 
virtual void foo(int, double, double); //this doesn't work 
}; 

溶液があり得ます。についてどう思いますか?

+1

機能オーバーロードは、**異なるAPI **を表します。抽象基本クラスは**一貫したAPI **を表します。そうではない、これは意味をなさない。 –

+0

あなたの例が 'class Derived:Base'を見つけられていませんか? – nonsensickle

+0

@ nononsensical:そうですね、私はちょうど編集しました。ありがとう – Ale

答えて

9

これらの2つの機能は異なります。後者は最初に上書きされません。

virtual void foo(int,double)=0; 
virtual void foo(int, double, double); 

第2のものは、派生するための新しい仮想関数です。

overrideを最後に置くと、コンパイルでは何も上書きしていないと不平を言います。これはC++ 11のチェックです。

virtual void foo(int, double, double) override; 

ユーザが確認するために、関数の最後で使用overrideを確認するために、純粋仮想関数をオーバーライドすることができます。 あなたの場合、2番目の関数はDerivedポインタまたはタイプを使用してのみアクセスできます。(ただし、純仮想関数が適切にオーバーライドされて実装されていなければインスタンス化することはできませんが、それまでは抽象クラスです)。したがって、それが仮想化するのは、とにかく基本メソッドをオーバーライドしていないオーバーヘッドであるので、Derivedから派生するクラスによってさらに追い越されることを意図していなければならない。

+0

この回答がポップアップしたときに、私は「オーバーライド」について書きました。 http://msdn.microsoft.com/en-us/library/vstudio/jj678987.aspx – Kupto

+0

@Kupto:なぜこの例では、最初にfuncC(double = 0.0)のオーバーライドが2番目のコードは動作しませんか? – Ale

+0

@Ale私はちょうど試しました。最初の例の 'override'キーワードはコメントを考慮すると重複しているようです。 – Kupto

4

できません。

Baseポインタがあり、Derivedオブジェクトを指しているとします。 Baseポインタを持つと、Baseのインターフェイスにのみアクセスできます(ポインタをDerivedにキャストしない限り、これは必要なものではありません)。

+0

はい、これは問題です。だから唯一の解決策は抽象クラスを作成することですが、インタフェースは作成しません。ではない? – Ale

+0

@Ale - あなたの意見は分かりません。 C++の 'interface'と' abstract class'の違いは何ですか? –

+0

[link](http://stackoverflow.com/questions/15387581/more-methods-in-derived-classes-than-base-class)、派生クラスは抽象クラスより多くの機能を持つことができます。代わりに、インターフェイスはメソッドの数を制限します(私の意見では)。 – Ale

3

オーバーロードされた関数は、単に別のものと同じ名前を持つ関数ですが、別のパラメータのセットを受け入れる、つまりの異なる関数です。 1つ以上のオーバーロードされた関数が仮想であるかどうかとは関係ありません。

あなたが提示した例では、ユーザーが純仮想関数をオーバーロードする可能性がありますが、オーバーライドした後でなければなりません。そして、基底クラスから関数に直接アクセスすることはできませんでした。基底クラスポインタを派生クラスポインタにキャストする必要があります。

0

他人から指摘されているように、うまくいきません。

はより離散的に、ここでは関数のシグネチャが異なっているとして、それが上書きされていない

Derived d; 
d.foo(5, 10.0); // Works as expected 

Base &b = d; // b is polymorphic 
b.foo(3,10,4); // foo(int, double, double) is not in class Base, hence compile-time resolution fails! 
0

何が起こるかです。関数をオーバーライドする多型ルールによれば、関数のシグネチャと型は同じでなければなりません。

この場合、これらの機能は異なります。 仮想void foo(int、double)= 0; 仮想ボイドfoo(int、double、double);

0

基本クラスのfooのオーバーロードが最も簡単な解決法ですか?

class Base 
{ 
public: 
Base(); 
virtual ~Base(); 
virtual void foo(int,double)=0; 
virtual void foo(int,double,double)=0; 
}; 
関連する問題