ООП проектный вопрос о наследовании и перегрузке операторов - PullRequest
7 голосов
/ 16 февраля 2011

В математическом пакете я пытаюсь создать классы для различных типов матриц, таких как типичная прямоугольная матрица, треугольная матрица, диагональная матрица и т. Д. Причина, естественно, заключается в том, чтобы сэкономить на эффективном хранении и эффективной реализации алгоритма для специальных матриц.Но я все же хотел бы иметь гибкость перегруженных операторов, где 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) Класс будет огромен с возможным синтаксисом регистра переключателей для проверки типа матрицы перед запуском конкретного алгоритма.Для каждого бинарного оператора у меня должно было бы быть n ^ 2 случая, где n - это номер типа матрицы, который я хочу реализовать.Может также быть кошмаром обслуживания.

Похоже, без детализации перегрузки оператора я мог бы использовать Заводской шаблон или Шаблон посетителя , но не с операционными перегрузками,Как лучше всего решить эту проблему?

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

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

Исправления:

4/25/2011: добавлено больше ресурсов Iдо сих пор не нашел об этой проблеме.

1 Ответ

7 голосов
/ 16 февраля 2011

Если бы это был мой проект, я бы выбрал вариант # 1: определить абстрактный класс Matrix, который наследуется более конкретными типами, такими как TriangularMatrix. Это позволит вам создавать операторы (даже если указанные операторы просто генерируют исключение NotImplementedException), которые вы затем можете переопределить в производных классах. Это также позволит вам работать с любой матрицей в виде Матрицы, с этим общим набором функций.

Единственное, что вы потеряете, это проверка компилятором того, что вы фактически переопределили методы и операторы; поскольку операторы являются статическими, их нельзя сделать абстрактными. Вы можете обойти это, если хотите, заставляя операторы в базовом классе просто вызывать эквивалентный именованный метод (например, + вызовет метод Add), который МОЖЕТ быть абстрагирован в базовом классе, таким образом заставляя дочерние классы реализовать его.

Математический вопрос: можно ли добавить треугольную матрицу к прямоугольной или же оба дополнения должны совпадать по типу и / или размерам? Если это первое, рассмотрите возможность реализации оператора в базовом классе Matrix, и пусть этот оператор реализует шаблон стратегии, вызывая внутренние классы, которые могут выполнять фактические манипуляции для каждой комбинации типов. Если это последнее, просто переопределите реализацию базового класса допустимых операторов для этого типа матрицы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...