[C++]Designfrage (Klasse)

Online-Skater

Erfahrenes Mitglied
Hallo Tutorianer,

bin zur Zeit wieder bissl am üben und diese Frage brennt schon länger auf meinen Lippen. Ich habe eine Klasse und Methoden welche an bestimmten Bedingungen geknüpft sind. Konkret geht es um eine Matrix Klasse mit der man Matrizen erstellen, bearbeiten und berechnen kann. Noch konkreter, die Methode toInverse() soll ein Objekt der Klasse Matrix zurückgeben sofern die Matrix sich invertieren läasst, dies ist an mathematische Bedingungen geknüpft, zum einen muss sie quadratisch sein und zum anderen eine Determinante ungleich 0 besitzen.

Frage: Was kann man machen um das Problem eleganter zu lösen als ich dies getan habe ?
C++:
// Try to transform to inverse matrix with "adjunkte"
Matrix Matrix::toInverse()
{
  // if matrix have no square format then dont exits the inverse
  if (!_square)
  {
      throw std::exception();
  }

  const double det = this->determinant();
  if (det)
  {
    // create inverse matrix
    Matrix inverseMatrix(_row, _col);

    // create temporary matrix for computing the complementary matrix
    usint size = _row - 1;
    Matrix tmp(size, size);

    // loop for every row
    for(usint i = 0; i < _row; i++)
    {
        // loop for every column
        for(usint j = 0; j < _col; j++)
        {
            // position counter for collected values (which are not striked)
            usint x = 0, y = 0;
            // interior loop for striking row and column
            for(usint k = 0; k < _row; k++)
            {
              for (usint l = 0; l < _col; l++)
              {
                if (i != k and j != l)
                {
                  tmp._arr[x][y] = this->_arr[k][l];
                  y++;
                  if (y == size)
                  {
                    y = 0;
                    x++;
                  }
                }
              }
            }
            // complementary matrix value
            inverseMatrix._arr[j][i] = (std::pow(-1.0, j+i) * tmp.determinant()) / det;
        }
    }
    return inverseMatrix;
  }
  // joa was hier zurückgeben  :(
}

Diese Lösung ist denkbar schlecht denn Exceptions sollten ja nur eingesetzt werden bei Ausnahmefällen...

Folgende Lösungen kann ich mir vorstellen, möchte aber gern etwas professionellere Lösungen hören.

1. Einen boolschen Referenzparameter übergeben der Erfolg/Mißerfolg speichert.
2. Verschiedene (2) Klassen für quadratische und unquadratische Matrizen (hier wäre noch das Problem das trotzdem die Determinante 0 sein kann und ich somit keine inverse Matrix zurückgeben kann)
3. Exceptions wobei dies hier dann keine Ausnahmen mehr darstellt sondern alltäglich sein kann (hängt natürlich vom Programmierer ab) ->unschöne Lösung ?

Also wie ihr seht ein Designproblem was ich an diesem konkreten Beispiel erläutere aber mir in etlichen anderen Fällen auch schon begegnet ist.

Danke für hilfreiche Vorschläge ;-)

mfg
 
1. "Referenzparameter" Idee gefällt mir nicht ;-)

2. Definitiv keine gute Lösung.

3. Sooo schlecht ist die Exception Sache nicht. Vorallem weil ein Anwender der Matrix vorher vielleicht eh prüfen sollte, ob sie quadratisch ist oder nicht !

4. Meine Idee:
Lass dir einen Matrix-Pointer zurückgeben der bei einer nicht quadratischen Matrix NULL ist. (Ist auch effizienter)

Gruß
Christian
 
Nja warum zeiger effizienter als Referenzen sind ... steht in den Sternen ;)

std::logical_error wäre auch eine mögliche Exception die geworfen werden kann. Oder du machst es so:
C++:
const std::pair<bool, Matrix> Matrix::toInverse() const
...
 
Ok danke für die Antworten
ich werde dann wohl doch mit Exceptions fortfahren und std::logical_error wäre am logischsten :)

Die Idee mit dem Pair ist mir noch nicht gekommen, nicht schlecht bis auf das man den < und == operator überladen sollte und das wäre wenig sinnvoll für meine Klasse und die Lösung ist fast identisch wie mit dem Referenzparameter ;-)

Ich dachte eher an sowas wie ein Entwurfsmuster Konzept oder so aber damit kenne ich mich noch zu wenig aus :rolleyes:
Im Prinzip wäre es cool wenn es gehen würde das Methodenaufrufe abhängig machen kann von Membervariablen also wenn "square" true ist dann kann ich toTriangle() und toInverse() aufrufen. Aber sowas ist wohl Wunschdenken bzw. völliger Blödsinn ^^


Ich versuche es mal weiter wird vielleicht noch die eine oder andere frage kommen.

mfg
 
Zuletzt bearbeitet:
Zurück