Ich schreibe eine lineare Algebra-Bibliothek (kurz gesagt, eine Schulaufgabe), die Matrizen, Vektoren usw. enthält. Beim Erstellen dieser Bibliothek werden Funktionen erstellt, die mathematische Operationen an Objekten ausführen. Zum Beispiel Matrix transponieren, Matrix invertieren, Vektor normalisieren usw.
Ich war neugierig, was die "beste Vorgehensweise" für diese Art von Funktion ist ... Soll ich die Funktion als Mitgliedsfunktion oder als Nichtmitglied definieren? (Aus Gründen der Übersichtlichkeit / Bibliothek verwenden Sie Sake)
Beispiel:
//Member function way:
B = A.transpose();
C = A.inverse();
//Non-member function way:
B = linalg::transpose(A); //Non-member transpose function in linear algebra namespace
C = linalg::inverse(A);
Gibt es einen Standard für diese Art von Operationen? Oder gibt es zumindest eine gemeinsame Art und Weise, wie Menschen dies tun? Ich neige zur ersten Option, würde aber gerne wissen, ob dies empfohlen wird.
Sowohl Mitglieder- als auch Nicht-Mitglieder-Funktionen haben neben dem bloßen Geschmack echte Vorteile. Beispielsweise
matrix
müssen Sie wahrscheinlich die zugrunde liegenden Arrays verwenden, die zum Implementieren einer Klasse verwendet werdenprivate
, esfriend
sei denn, Sie verwenden Memberfunktionen. In dieser Hinsicht kann ein OO-Design besser sein.Bedenken Sie jedoch, dass Informatiker von Zeit zu Zeit komplexe mathematische Formeln implementieren müssen, ohne immer zu wissen, was sie wirklich tun. Wenn ich das tun muss, bevorzuge ich Funktionen, die keine Mitglieder sind, da das "visuelle" Ergebnis näher an der ursprünglichen mathematischen Formel liegt (da mathematische Formeln im Allgemeinen einen funktionalen Stil verwenden).
Am Ende ist die Antwort dieselbe wie die von Doc Brown: Es ist Geschmackssache. Kurz gesagt, Sie könnten erwägen, eine Bibliothek im OO-Stil mit Mitgliedsfunktionen zu schreiben (einfacher zu schreiben, nein
friend
) und dann Nicht-Mitgliedsfunktionen zu schreiben, um dieselben Aufgaben auszuführen, bei denen die Argumente einfach an die Mitgliedsfunktionen weitergeleitet werden. Es ermöglicht Ihnen, konsistent zu sein und dem Benutzer die Wahl zu lassen, was er für am besten hält.quelle
Wenn Sie tiefer in Ihre Problemstellung eintauchen, wird klar, dass Sie irgendwann benutzerdefinierte Datenstrukturen verwenden, die bestimmte mathematische Einheiten darstellen. Zum Beispiel könnten Sie eine Matrix my mittels eines n-dimensionalen Arrays darstellen. Um auf Ihr Beispiel einzugehen,
(Das C ++ - Beispiel ist vereinfacht, Sie können Vorlagen und dergleichen verwenden.)
Der zu berücksichtigende Punkt ist die einfache Verwendung von benutzerdefinierten Datenstrukturen in beiden Fällen. C ++ (oder jedes objektorientierte Programm) als Sprache ist an sich leistungsfähiger und dies gilt für den Benutzer der Bibliothek ebenso wie für den Implementierer. Ich habe in der Vergangenheit nur C-Bibliotheken verwendet, und diese benutzerdefinierten Datenstrukturen scheinen sich im Nu zu verbreiten! Während Interoperabilität mit letzteren leichter zu erreichen ist (mit speziellen Konstruktoren, vielleicht?)
Wenn Sie C ++ verwenden, ist ein objektorientierter Ansatz auf jeden Fall empfehlenswert.
quelle
transpose
Beispielen. Der Hauptgrund dafür, dass C ++ einfacher ist, ist, dass die Semantik von Kopieren und Zuweisen tatsächlich funktioniert.A = B
kann in C kompilieren, tut aber wahrscheinlich das Falsche.