Как лучше всего позволить пользователю переопределить метод класса? - PullRequest
0 голосов
/ 09 ноября 2019

У меня есть библиотека с полностью общей реализацией, за исключением одного класса A. Этот класс имеет только одну функцию int format(int i){}, но его нельзя использовать как есть: format зависит от каждого отдельного приложения и должен быть определен пользователем. В частности, format содержит довольно много операторов if-then, которые необходимо правильно установить для среды приложения. Однако остальная часть библиотеки является полностью общей и будет работать с любым выбором format, который соответствует определенным спецификациям.

Вопрос: Как лучше всего позволить пользователю моей библиотеки определить, как format работает? Это необходимо сделать на уровне кода (в отличие от простого использования файла конфигурации).

Очевидная идея состоит в том, чтобы пользователь напрямую переписал определение format непосредственно в исходном коде, ноэто не самый элегантный способ сделать это.

Другая идея заключается в использовании наследования: пусть пользователь определит класс userA, наследующий от A, а затем скроет функцию format,Но остальная часть библиотеки использует класс A вместо userA. На этом этапе можно было бы заменить все экземпляры A на имя типа desiredA, а затем дать пользователю возможность определить это имя типа userA. Это тоже не очень элегантно.

Должен быть лучший способ сделать это правильно?

1 Ответ

1 голос
/ 09 ноября 2019

Вот метод, который я использовал в прошлом.

  1. Добавьте возможность разрешить пользователю регистрировать функцию по своему выбору.
  2. Если определенная пользователем функция имеетбыл зарегистрирован, позвоните. В противном случае используйте некоторую функцию по умолчанию.
using UserFunctionType = int(*)(int i);
UserFunctionType registeredFunction = nullptr;
void registerUserFunction(UserFunctionType f) { registeredFunction = f; }

int format(int i)
{
   if ( registeredFunction ) 
   {
      return registeredFunction(i);
   }
   else
   {
      // Some default implementation
   }
}

Код пользователя будет выглядеть примерно так:

int myFunction(int i)
{
   // Return whatever makes sense.
}

int my_init()
{
   registerUserFunction(myFunction);
   return 0;
}

// Make sure my_init() gets called at program startup time.
static int dummy = my_init();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...