2017-03-06 10 views
1

引数として整数または文字列のいずれかを取ることができるgetNameメソッドを持つ基本クラスAがあるとします。だから私は、作成:C++で複数の引数型を持つ仮想メソッド

virtual string getName(int index) = 0; 
virtual string getName(string key) = 0; 

は今、私は2件の異なるサブクラスのBを作成したいとC. BにのみgetName(int index)必要とCのみgetName(string key)を必要とします。 しかし、両方のサブクラスで両方のメソッドを上書きしないと、エラーが発生します。しかし、私がこれを行うと、BとCは空の方法を持っています。他のケースは必要ありません。getName

どうすればこの問題を解決できますか?単純にすることで

+0

(名前の貼り付けが悪である)テンプレートの代わりに、名前の貼り付けを使用して、ヴィットリオ・ロメオの溶液と同じですgetNameにintまたはstringパラメータをサポートするかどうかを知りますか? – marcinj

+0

@AlexandreTHOUVENIN私はそれを疑っています。おそらく、定義がint型とstring型の両方で同じであってはなりません。 – George

+0

'A'の使用例を追加してもらえますか?同じ基本クラスに 'getName'の両方のオーバーロードが必要なのはなぜですか? –

答えて

-2

は、彼らは純粋仮想が、ちょうど仮想作りません:getName(int)をサポートするものとgetName(string)をサポートしています1:あなたは、実際には2つの異なるインタフェースをしたいよう

struct Blub 
{ 
    virtual void do1() {} // default definition 
    virtual void do2() = 0; //has to be overridden 
}; 
+0

OPは、派生クラスで定義された2つのメソッドの少なくとも1つを望んでいると思います。 – Nyashes

3

ですね。

struct GetNameInt { 
    virtual string getName(int index) = 0; 
}; 

struct GetNameStr { 
    virtual string getName(string key) = 0; 
}; 

struct B : GetNameInt { /* ... */ }; 
struct C : GetNameStr { /* ... */ }; 

あなた本当には、同じインターフェイスを持つ単一の基本クラスを必要とし、あなただけで、あなたがしたい場合がありますstringまたはintを、必要があるでしょうかどうか、実行時でわかっている場合std::variant

struct GetName { 
    virtual string getName(std::variant<int, string>) = 0; 
}; 
1

あなたは継承を正しく使用していません。 SOLID principlesについてもっと読むことを強くお勧めします。次の2つのクラス(インタフェース)にクラスAを分割する必要が

- AAとAAはのgetNameを開催する(int型のインデックス)とのgetName(文字列キー)を持っているだろう、のようなAB、:

class A { 
//does not define neither of the getName methods 
} 

class Aa { 
    virtual string getName(int index) = 0; 
} 

class Ab { 
    virtual string getName(string key) = 0; 
} 

class B : A, Aa { 
    //inherits from A and defines string getName(int index) 
} 

class C : A, Ab { 
    //inherits from A and defines string getName(string key) 
} 
0

[OK]を

struct CommonA //protect this if possible 
{ 
    template<class type> 
    string getGenericName(type index); 
    virtual ~CommonA() {} 
}; 

template<class indexType> 
struct A : CommonA 
{ 
    virtual string getName(indexType index) = 0; 
}; 

struct B : A<int> 
{ 
    string getName(int index) override {cout << index << "\n"; } 
}; 
struct C : A<string> 
{ 
    string getName(string index) override {cout << index << "\n"; } 
}; 

template<class type> 
string CommonA::getGenericName(type index) 
{ 
    cout << "generic call: \n"; 
    return dynamic_cast<A<type>*>(this)->getName(index); 
} 

int main() 
{ 
    CommonA b = B(); 
    CommonA c = C(); 
    b.getGenericName(1); 
    c.getGenericName(string("hello world")); 
} 

(注)このソリューションは、標準的なOOPのソリューションが、テンプレートソリューションではないこと:私はまだいくつかの型の安全性を維持しながら、BとCの間で共通の親を維持し、時間チェックをコンパイルするために思い付くことができ、最高。

編集:私の<をテンプレート、あなたのベース・インターフェースを使用して、あなたのクラスBとCを使用する場合>クラスはどのように、

+0

仮想のデストラクタを 'CommonA'に置き、' static_cast'ではなく 'dynamic_cast'を使用してより良い型安全性を確保してください。 – Jarod42

+0

@ Jarod42完了、あなたが改善の他の部屋を見つければ、さらに編集すること自由に感じてください – Nyashes

+0

私に見せかけるようです。私の意見では、少なくともテンプレートと継承を混ぜるのは悪いことです。 – zett42

関連する問題