Реализация интерфейса для статического полиморфизма

Как реализовать интерфейс так, чтобы в каждом классе должны были быть реализованы все функции из класса интерфейса?

Нашел такое решение:

  1. Программист, который хочет задать определенный интерфейс для всех дочерних классов, составляет список обязательных функций.
  2. Каждую из этих функций нужно якобы вызвать в базовом классе.
  3. Не зная ничего о реализации дочерних классов, это можно реализовать с помощью хитрости - вызываем функцию через указатель.

По идее, код не должен компилироваться, если в каком-то из дочерних классов нет реализации функции из списка. Но... оно компилируется.

Первый раз я расстроен, что мой код компилируется.

Помогите сломать компиляцию :-)

Есть небольшие требование: Не должно быть дополнительных вычислений в run-time

template <class AnyFruitType>
struct IFruit{
  void _() {
      static_cast<AnyFruitType*>(this)->foo_0();
      static_cast<AnyFruitType*>(this)->foo_1();
      static_cast<AnyFruitType*>(this)->foo_2();
    }
};

// Наследуюсь от класса-интерфейса, полагая, что в нем произойдет проверка
struct apple : IFruit<apple>{
  void foo_1(){}
  void foo_2(){}
  // void foo_3(){} делаем вид, что не реализована одна из функций
};

struct banana : IFruit<banana>{
  void foo_1(){}
  void foo_2(){}
  void foo_3(){}
};


int main() {
  apple a;
  banana b;

  a.foo_1();
  b.foo_1();
  //a.foo_3(); Код компилируется, если нет вызова нереализованной функции.
}

Ответы (1 шт):

Автор решения: user7860670

Чтобы такая проверка в базовом классе заработала, проверяющую функцию необходимо инстанцировать. Чтобы не было бессмысленных вызовов функций необходимо брать указатели на них. Зато имеет смысл делать проверку в конструкторе, чтобы он инстанцировался при генерации конструктора класса-наследкика.

template<typename AnyFruitType>
struct IFruit
{
    constexpr IFruit(void) noexcept
    {
        static_cast<void>(&AnyFruitType::foo_1);
        static_cast<void>(&AnyFruitType::foo_2);
        static_cast<void>(&AnyFruitType::foo_3);
    }
};

online compiler

→ Ссылка