2010-11-26 22 views
1

C++の継承の問題

Class A 
{ 
    virtual int doSomethingCool() = 0; 
}; 

Class B : public A 
{ 
    int doSomethingCool(); 
}; 

は、今の問題は、私はとしてインターフェイスに依存しているwhcihクラスのセットを持って、好きです。私は派生クラスの1つの関数のプロトタイプを変更する必要があります。つまり、パラメータを渡す必要があります。

Class C: public A 
{ 
int doSomethingCool(int param); 
}; 

どのように私はこれを達成することができますか?

+1

これは本当にC++ですか? – Chubsdad

+0

私は擬似コードで簡略化しました。 –

+2

2番目のクラスが別のものを必要とする場合は、別のインターフェイスか初期インターフェイスが間違っていることを意味します。 – David

答えて

2

いいえ、基本クラスに追加する必要はありません。

class A 
{ 
public: 
    virtual int doSomethingCool() = 0 {} 
}; 

class B : public A 
{ 
public: 
    int doSomethingCool() {return 0;} 
}; 

class C: public A 
{ 
private: 
    int doSomethingCool(); // hide base class version! 
public: 
    int doSomethingCool(int param) {return param;} 
}; 

基底クラスのポインタを介して行わ場合は、まだdoSomethingCool()を呼び出すことができます。

struct A 
{ 
    virtual int doSomethingCool() = 0; 
}; 

struct A_specific : A 
{ 
    virtual int doSomethingCoolWithThis(int i) = 0; 
}; 

class ConcreteA : public A 
{ 
    int doSomethingCool() { return 0; } 
}; 

class ConcreteA_specific : public A_specific 
{ 
    int doSomethingCool() { return 0; } 
    int doSomethingCoolWithThis(int param) { return param; } 
}; 

は、その後、私はプログラムになります。私は別の、より具体的な、インタフェースを導入しているだろう

C c; 
//c.doSomethingCool(); // doesn't work, can't access private member 
c.doSomethingCool (42); 
A &a = c; 
a.doSomethingCool(); 
//a.doSomethingCool (42); // doesn't work, no member of A has that signature 
0

doSomethingCool()は、のパラメータをAに設定します。

class A 
{ 
public: 
    virtual void doSomethingCool(int param) = 0; 
}; 
+0

それはAの他のクラスの依存関係を壊すでしょう。 –

+0

@Ricko:そうですが、クラス 'C'のパラメータリストを変更すると、方法 - それを隠す。クラス 'C'のクラス' A'の 'doSomethingCool()'メソッドをオーバーライドしようとすると、それはあなたが思うことをしません。 'A'クラスは抽象クラスなので、パラメータなし' doSomethingCool() 'をまだ実装していないので、' C'のインスタンスを作成することはできません。 –

0

問題ありません。あなたはそれを行うことができます。唯一の注意点は、基本クラス仮想関数のオーバーライドとして扱われないことです。

class A 
{ 
public: 
    virtual void doSomethingCool() = 0; 
}; 

class B : public A 
{ 
public: 
    void doSomethingCool(); 
}; 

class C: Public A 
{ 
public: 
    void doSomethingCool(int param); 
}; 


int main(){} 

だから、技術的には可能ではあるが、あなたが本当に

一つの選択肢はにデフォルト引数を提供することで、あなたのインターフェイスクラスAの設計でrelookすることをお勧めします:: doSomethingCool

virtual void doSomethingCool(int = 0) = 0; 
+0

[それは基本クラスの関数をオーバーライドしません、それを隠す](http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9)、私はそれですOPが意図したものではないことは間違いありません。 –

+0

@In silico:あなたのコメントと私の更新はお互いに交差しました – Chubsdad

+0

ああ、私はあなたの編集を見ました。 :-) –

1

これをインターフェイスに追加し、既存のメソッドを呼び出すようにデフォルト設定します。デフォルトを行う必要はありませんが、純粋なものにしないと、派生したすべてのクラスを実装する必要があります。それを未定義にしたり、投げたりする方が良いかもしれません。あなたが達成したいことにかかっています。

class A 
{ 
public: 
    virtual int doSomethingCool() = 0; 
    virtual int doSomethingCool(int param) {doSomethingCool()}; 
}; 
+0

クラス 'C'はまだパラメータなし' doSomethingCool() '純粋仮想関数を実装しなければならないことに注意してください。そうしないと、' C'のインスタンスを作成できなくなります。 –

0

これは構文上正しいとは限りません。C++。

いいえいいえ、プロトタイプを変更することはできません。どのように使用されますか?パラメトリックでないバージョンが呼び出されると、パラメタの値はどのようになりますか?

0

正しいインターフェイス:

int main() 
{ 
    const A& a1 = ConcreteA(); 
    const A_specific& a2 = ConcreteA_specific(); 

    a1.doSomethingCool(); 
    a2.doSomethingCool(); 
    a2.doSomethingCoolWithThis(2); 
} 

あなたに別のアイデアを伝えよう;-)

幸運を祈る!