C++: как унаследоваться одновременно от базового класса и «интерфейса» при этом если оба они имеют общий «интерфейс»? Глоссарий: интерфейсом будем считать класс с чисто виртуальными функциями без состояния.
Допустим есть некий базовый интерфейс. От него наследуются другие интерфейсы. От них - рабочие классы. Примерно так:struct block_i
{
virtual ~block_i() = default;
virtual bool is_done() const = 0;
//...
};
template
struct consumer_block_i : public block_i
{
virtual void register_producer(producer_block_i&) = 0;
//...
};
template
struct action_block : public consumer_block_i
{
virtual bool is_done() const override { return false; }
virtual void register_producer(producer_block_i&) override {}
//...
};
Таких классов как action_block несколько, и все они содержат в том числе некий одинаковый код. Хотелось бы поместить его в базовый класс, допустим block_base, унаследовать его от block_i. чтобы получилось примерно так:struct block_base : public block_i
{
virtual bool is_done() const override { return false; }
};
template
class action_block
: public virtual block_base
, public virtual consumer_block_i
{
virtual void register_producer(producer_block_i&) override {}
//...
};
Но сделать так в C++ я не могу (ну или не знаю как) - получаю ошибку компиляции. В C# так сделать можно:interface IBlock
{
bool IsDone();
}
interface IConsumer : IBlock
{
void RegisterProducer(IProducer producer);
}
class BlockBase : IBlock
{
public bool IsDone() { return false; }
}
class Consumer : BlockBase, IConsumer
{
private IProducer producer_;
public void RegisterProducer(IProducer producer) { producer_ = producer; }
}
Вопрос: как реализовать такое же на C++? Если это возможно разумеется. В интерфейсы помещать некие дефолтные реализации не хочется.

21 Авг 2019 в 07:01
189 +1
1
Ответы
1

В C++ нет возможности множественного наследования от виртуальных базовых классов с общими функциями. Однако, можно достичь подобного эффекта, используя механизм наследования шаблонов (CRTP - Curiously Recurring Template Pattern).

В вашем случае, вы можете определить шаблонный класс block_base, который будет предоставлять общий код для классов, наследующихся от него. Примерно так:

template <class T>
struct block_base
{
bool is_done() const { return false; }
};
template <class T>
struct consumer_block_i : public block_base<T>
{
void register_producer(producer_block_i<T>& producer) {}
};
template<class T>
struct action_block : public consumer_block_i<T>
{
// дополнительный код...
};

Теперь класс action_block может наследоваться от consumer_block_i с общим кодом через шаблонный базовый класс block_base. В этом случае, код из block_base будет доступен внутри action_block.

Надеюсь, это поможет вам реализовать желаемую функциональность в вашем коде на C++.

20 Апр в 13:09
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 83 722 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир