C ++ множественное наследование и типирование утки

Я пытаюсь найти способ выразить общий базовый тип для двух объектов, которые наследуют пару похожих интерфейсов.

Посмотрите код ниже: очевидно, что должен быть возможный общий базовый тип для fb1 и fb2 (например, что-то вроде IFizzBuzz).

Кто-нибудь знает, возможно ли это (не требуя шаблонов, если это возможно 🙂

Спасибо !

#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

Решение

Есть 3 общих базовых класса для FizzBuzz1 а также 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();
4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]