2017-07-27 14 views
1

私は、同じようなインターフェイスのペアを継承する2つのオブジェクトの共通基底型を表現する方法を見つけようとしています。C++多重継承とダックタイピング

以下のコードを参照してください:fb1とfb2(たとえば、IFizzBu​​zzのようなもの)に共通の基本タイプが存在するはずです。それが可能であれば

誰でも可能であれば

感謝:-)テンプレートを必要とせず、(知っています!

#include <memory> 
#include <iostream> 

struct IFizz { 
    virtual void DoFizz() = 0; 
}; 
struct IBuzz { 
    virtual void DoBuzz() = 0; 
}; 

struct Fizz : public IFizz { 
    void DoFizz() override { 
    std::cout << "Fizz\n"; 
    } 
}; 

struct Buzz1 : public IBuzz { 
    void DoBuzz() override { 
    std::cout << "Buzz1\n"; 
    } 
}; 
struct Buzz2 : public IBuzz { 
    void DoBuzz() override { 
    std::cout << "Buzz2\n"; 
    } 
}; 

struct FizzBuzz1 : public Fizz, public Buzz1 { 
}; 
struct FizzBuzz2 : public Fizz, public Buzz2 { 
}; 

// Expected "Base type" of FizzBuzz1 and FizzBuzz2 
struct IFizzBuzz : public IFizz, public IBuzz { 
}; 

int main() 
{ 
    { 
    FizzBuzz1 fb1; 
    fb1.DoFizz(); 
    fb1.DoBuzz(); 
    } 
    { 
    FizzBuzz2 fb2; 
    fb2.DoFizz(); 
    fb2.DoBuzz(); 
    } 
    // { 
    // // The line below is not legit and does not compile 
    // std::unique_ptr<IFizzBuzz> ifb(new FizzBuzz1()); 
    // ifb->DoFizz(); 
    // ifb->DoBuzz(); 
    // } 
    return 0; 
} 
+0

失敗した文は、 'IFizzBu​​zz'が' FizzBu​​zz1'の明白な基本クラスである場合にのみ有効です。しかし、 'FizzBu​​zz1'は' IFizzBu​​zz'から継承しません。共通の基盤が必要な場合は、 'FizzBu​​zz1'は直接的または間接的にそれを曖昧さなく継承する必要があります。 – Peter

+0

@Peter:これが「ダックタイピング」というタグを追加した理由です;-) –

答えて

4

FizzBuzz1FizzBuzz2

  • IFizz
  • IBuzz
  • Fizz

のための3つの共通の基本クラスは、これら2の定義を変更せずにありますが、方法はありませんまたそれらを持っているIFizzBuzzをベースとする。

ただし、IFizzBuzzを派生し、その2つのうちの1つに委任することができます。

template <typename FizzBuzz> 
struct Wrapper : IFizzBuzz 
{ 
    void DoFizz() final { fizzBuzz.DoFizz(); } 
    void DoBuzz() final { fizzBuzz.DoBuzz(); } 
private: 
    FizzBuzz fizzBuzz; 
} 

これは、たとえば次のように使用できます。

std::unique_ptr<IFizzBuzz> ifb = std::make_unique<Wrapper<FizzBuzz1>>(); 
ifb->DoFizz(); 
ifb->DoBuzz(); 
ifb = std::make_unique<Wrapper<FizzBuzz2>>(); 
ifb->DoFizz(); 
ifb->DoBuzz();