Вопрос проектирования ООП по наследованию и перегрузке операторов

Для математического пакета я пытаюсь иметь классы для различных типов матриц, таких как типичная прямоугольная матрица, треугольная матрица, диагональная матрица и т. Д. Причина, естественно, заключается в том, чтобы сэкономить на эффективное хранение и эффективная реализация алгоритмов для специальных матриц. Но я все же хотел бы иметь гибкость перегруженных операторов, где C = A + B будет принимать A и B как любой тип матрицы и возвращать соответствующий результат (результат может быть понижен до типичной прямоугольной матрицы, если один из операндов прямоугольный) .

Я придумал 2 возможные идеи, обе из которых беспорядочные:

(1) Интерфейс IMatrix, в котором будут перечислены все методы, которые необходимо реализовать для каждого типа матрицы, например, транспонирование, обратное преобразование. и т.д., эффективная реализация которых различна для каждого типа матрицы. Здесь две проблемы: (a) Перегрузки операторов - это статические методы, поэтому они не могут быть перечислены в интерфейсе или даже в базовом классе, реализующем интерфейс. Перегрузки операторов должны быть написаны в каждом классе отдельно, и я не могу достичь операции типа C = A + B (как я уже упоминал выше), без беспорядочной проверки типов и преобразования клиентского кода, чего я действительно хочу избежать. (b) У меня не может быть обоих операндов в качестве интерфейса, когда я определяю перегрузки операторов: т.е. я не могу делать следующее, скажем, в классе DiagonalMatrix:

public override IMatrix operator +(IMAtrix lhsMatrix, IMatrix rhsMatrix)
{ ... }

(2) Может иметь один класс Matrix с переменной типа матрицы, хранящейся в классе ( может быть Enum). В зависимости от типа мы можем реализовать структуру данных и алгоритмы. Тогда перегрузка оператора будет работать без проблем. Здесь есть одна проблема: (a) Класс был бы огромным с возможным синтаксисом switch-case для проверки типа матрицы перед запуском конкретного алгоритма. Для каждого бинарного оператора я должен иметь n ^ 2 случаев, где n - это номер типа матрицы, который я хочу реализовать. Также может быть кошмаром технического обслуживания.

Похоже, если бы оператор не перегружал детали, Я мог бы использовать шаблон Factory или шаблон Visitor , но не так с перегрузками op. Как лучше всего решить эту проблему?

Ресурсы, которые я нашел до сих пор:

  1. Один связанный поток здесь.
  2. Объяснение аналогичной проблемы , с которой столкнулся разработчик другого пакета ОС C # Numerics.

Редакции:

25.04.2011: Добавлены дополнительные ресурсы, которые я нашел по этой проблеме на данный момент.

7
задан Community 23 May 2017 в 12:13
поделиться