Прошу прощения, если этот вопрос был задан раньше, я очень старался найти что-то подобное, но я даже не был уверен, что искать.Каков правильный способ определения интерфейса самореференции?
Предположим, что у меня есть следующий интерфейс (это просто пример, мой конкретный случай не имеет ничего общего с операторами или дополнение):
class AddAndSub
{
public:
virtual AddAndSub operator +(AddAndSub const &) = 0;
virtual AddAndSub operator -(AddAndSub const &) = 0;
}
С a + b
могут быть выражены как a - (-b)
и a - b
как a + (-b)
(для простоты предположим, что отрицание хорошо определено для всех типов получения), мой первый инстинкт заключался в том, чтобы имитировать это свойство в реализации, поэтому только один из операторов должен быть явно определен:
class AddAndSub
{
public:
virtual AddAndSub operator +(AddAndSub const & b)
{
return *self - (-b);
}
virtual AddAndSub operator -(AddAndSub const & b)
{
return *self + (-b);
}
}
Однако я не полностью удовлетворен своим решением, так как мне по-прежнему требуется определить хотя бы одну из операций, но он явно не применяется кодеком и не позволяет определить один результат в очень нежелательном сообщении об ошибке «Переполнение стека ». Я могу оставить интерфейс так, как он есть в первом примере, чтобы убедиться, что каждый класс, реализующий его, определяет необходимые методы, но по очереди приводит к большому количеству избыточного кода в нетривиальных случаях.
Есть ли способ уменьшить избыточность кода в подобных ситуациях, сохраняя при этом проверку времени компиляции и оставляя выбор того, какие методы реализовать пользователю интерфейса?
PS: Я знаю, что могу просто сделать один из этих методов чистым виртуальным, но тогда я не могу выбрать, какой метод я могу определить в случае, когда сложнее реализовать дополнение, чем вычитание (что TBH - это просто незначительный nitpick, но мне все еще интересно, есть ли лучший способ).
Боковое примечание: проектирование плюс оператор, который работает интуитивно понятным способом для иерархии открытого класса, является трудным. Просто сохранение a + b = b + a является огромной проблемой. Интересный базовый класс для правильного добавления некоторого очень производного класса тоже интересен. –
Я бы не использовал такие операторы в интерфейсе полиморфизма времени исполнения, иначе. виртуальных операторов. Это решительно ограничит гибкость вашего кода. Рассмотрите возможность использования полиморфизма времени компиляции и общего программирования при работе с арифметическими операторами. –