2017-07-27 55 views
1

我想找到一種方法來表示繼承一對類似接口的兩個對象的公共基類型。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

存在用於FizzBuzz1和3共同基類FizzBuzz2

  • IFizz
  • IBuzz
  • Fizz

在不改變這兩個的定義中,沒有辦法也有他們有IFizzBuzz作爲基地。

然而,您可以有一個派生IFizzBuzz的班級,並將其委託給其中一個班級,例如,

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();