2016-06-21 24 views
0

私は何かを投稿する前に通常ここで答えを見つけようとしますが、私の質問をどのように公式化するかはわかりません。インターフェイスと実装の両方から継承するC++

ここで私がやりたいことは...ベースインターフェイスと派生インターフェイスを定義したいと思います。次に、追加の変数とメソッドを使用して、基本インターフェースを実装したいと考えています。最後に、実装された基本インターフェイスから、派生インターフェイスからの派生クラスを実装したいと思います。私はあなたについて知りませんが、頭が痛いです。

私が以下のようにすると、DerivedFloatコードの下であいまいな定義が得られます。なぜなら、そのコードはIDerivedFloatで継承されたIBaseのGetBaseValueメソッドとBaseから継承されたGetBaseValueの両方を参照できるからです。

確かに、基本実装の拡張機能を使用するクラスを導出する方法と、必要なIDerivedFloatメソッドを実装することを確認する方法が必要です。

Now ...これは、概念的に達成しようとしていることを示すためのダミーの例です。それは実際の人生の例ではありません。

template <typename VALUE_TYPE> 
class IBase 
{ 
public: 
    virtual VALUE_TYPE GetBaseValue() const = 0; 
}; 

class IDerivedFloat : public IBase<FLOAT> 
{ 
public: 
    virtual void SetBaseValue(const FLOAT & value) = 0; 
}; 

// Implementation of Base 
template <typename VALUE_TYPE> 
class Base : public IBase<VALUE_TYPE> 
{ 
public: 
    VALUE_TYPE GetBaseValue() const { return m_BaseValue; } 

protected: 
    VALUE_TYPE m_BaseValue; 
} 

// Uses expanded Base AND implements IDerivedFloat 
class DerivedFloat : public Base<FLOAT>, public IDerivedFloat 
{ 
public: 
    void SetBaseValue(const FLOAT & value) { m_BaseValue = value }; 
} 
+0

*私はいつも何かを投稿する前に答えを見つけようとします* - あなたは "ダイヤモンドの継承"や[仮想継承]を見つけませんでした(http://stackoverflow.com/questions/21558/in-c-あなたの検索結果の中で何が仮想ベースクラスですか? – PaulMcKenzie

+0

C++の専門家ではありません。私は初めてダイヤモンドの継承という言葉を聞いたことがあります。 「仮想継承」に関する限り、私は持っています。しかし、明らかに、あなたのコメントから、私は自分の問題を解決するためにその情報をどのように知っていません。 – ThermoX

+0

コメントのリンクをクリックしましたか?それは基本的にあなたが受け入れた答えの複製です。 – PaulMcKenzie

答えて

3

あなたがこの問題を回避するためにvirtual inheritanceを使用することができます。

class IDerivedFloat : virtual IBase<FLOAT> 
{ 
public: 
    virtual void SetBaseValue(const FLOAT & value) = 0; 
}; 

template <typename VALUE_TYPE> 
class Base : virtual IBase<VALUE_TYPE> 
{ 
public: 
    VALUE_TYPE GetBaseValue() const { return m_BaseValue; } 

protected: 
    VALUE_TYPE m_BaseValue; 
} 

仮想継承を使用する代わりに、派生クラスに基本クラスのメンバの1つのインスタンスを提供しますそれがクラス階層に存在するたびに1つの

+0

ありがとうAndy!それは私がやりたかったことをしているように見える...そして、あなたの答えは、 "お前は仮想の継承を見ていない"よりも少し有益だと思う:) – ThermoX

0

あなたが遭遇したあいまいさの問題のために多重継承が問題になりますが、それを回避する方法があります。スーパーの名前と二重コロンで関数呼び出しを導くことによって、あいまいな関数を呼び出すスーパーをコンパイラに明示的に伝える必要があります。

例:
- CはAとB
から継承 - AとBの両方()関数を追加する必要があります。
- Cでは、A :: add()またはB :: add()を使用して、コンパイラに使用するコンパイラを指定する必要があります。詳細と、より完全な実装のための

リンク:http://www.cprogramming.com/tutorial/multiple_inheritance.html

+0

ありがとうございます。私は実際にそれを試みました!しかし、私に迷惑をかけたのは、派生クラスが両方の定義を持っているということです...私は避けようとしていました。これは、私が正しい方法で問題に近づいていない可能性があると結論づけます。 – ThermoX

+0

両方の機能を停止しようとしているのであれば、子機自体の別の機能でそれらをオーバーライドするのは唯一の考えですが、親の機能を取り除かずにカバーするだけです。彼らはまだアクセス可能です。私はあなたがクラスの一部だけを継承できるかどうか分からないので、それをすべて継承したり継承したりする必要があります。 – Kadima

+0

上記のアンディーが答えを出しました。あなたの助けてくれたカディマにもう一度感謝します。 – ThermoX

関連する問題