2017-07-27 35 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();