C ++多重继承和duck typing

时间:2017-07-27 11:11:24

标签: c++ multiple-inheritance duck-typing

我试图找到一种方法来表示继承一对类似接口的两个对象的公共基类型。

请参阅下面的代码:显然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;
}

1 个答案:

答案 0 :(得分:4)

FizzBuzz1FizzBuzz2

有3个常用基类
  • 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();