Was ist Ihre Regel für welche Funktionen, die in einer Klasse funktionieren, Member-Funktionen vs. Nicht-Member-Funktionen sein sollten? Zum Beispiel habe ich eine Klasse, die ein Labyrinth mit einer Matrix von Bools darstellt. Ich mache eine Funktion namens isConnected, die überprüft, dass 2 Punkte im Labyrinth in der gleichen Region sind (d. H. Es ist möglich, von A nach B zu reisen).
Sollte dies Mitglied oder Nichtmitglied sein? Was ist eine gute Regel?
Wann es zu einer Mitgliedsfunktion wird:
Wann es eine eigenständige Funktion machen soll
Herb Sutter sagt: "Wir wollen sie zu Nichtmitgliedsfreunden machen, wenn es vernünftigerweise möglich ist", und er ist schlauer als ich.
Nun, es gibt Argumente für beide.
zugunsten von Nichtmitgliedsfunktionen:
container.begin()
ist nicht gültig, wenn container
ein Array ist. Das macht es etwas komplizierter, generischen Code zu schreiben, der an Containern arbeitet. begin(container)
kann jedoch für jeden Typ gültig gemacht werden, sogar für eingebaute Typen wie Arrays) . Es kann auch Mixins durch Komposition viel sauberer machen, da es nicht erforderlich ist, dass sich der Benutzer durch Mitglieder "punktet", um zu dem Mixin-Objekt zu gelangen, auf dem Sie arbeiten möchten. Zugunsten von Elementfunktionen ist:
und ... das ist es. (Aber dieses Argument sollte nicht unterschätzt werden. Code Lesbarkeit ist wichtig, und wenn Leute es einfacher finden, die Member-Version zu lesen, ist das ein starkes Argument zu seinen Gunsten. Es produziert einfach keinen besseren Code. Aus einem strengen "besseren Code" Sichtweise sollten Nichtmitglieder bevorzugt werden, wenn möglich.
In diesem Fall würde ich für eine Mitgliedsfunktion gehen. Die Regel, der ich folge, ist, dass, wenn eine Funktion auf etwas zugreifen muss, das intern im aktuellen Zustand der Instanz ist, dann sollte sie Teil des "Bereichs" der Klasse sein. In diesem Fall hängt die Verbundenheit von A und B vom Zustand Ihrer Objektinstanz ab.
Natürlich könnten Sie am Ende eine Klasse mit zu vielen Verantwortlichkeiten haben. In diesem Fall tritt der einfache Faktor ein und du solltest überlegen, ob deine Klasse zu viel versucht. Es wäre dann praktisch, eine separate Klasse zu haben (wie in Ihrem Fall ein ConnectednessEvaluator), deren spezielle Rolle darin besteht, Algorithmen zu halten, die auf Ihre Maze-Instanzen traversieren und handeln können.
Ich verweise immer wieder auf FAQ 13.9 . Es ist keine exakte Wissenschaft, sondern eine Diskretion.
Es ist eine zu starke Vereinfachung zu sagen, dass, wann immer Sie Zugriff auf die Klasseninterna benötigen - Sie sollten ein Mitglied verwenden. Bemerkenswerte Beispiele sind die Stream-Insertion / Extraction-Operatoren ( >>
bzw. <<
) und die binäre +
.
In Ihrem Beispiel ist isConnected
eine Methode, um den Zustand des Objekts zu testen, d. h. einen Inspektor und einen idealen Kandidaten für die Mitgliedschaft.
Das einzige, was ich dazu tue, Nicht-Member-Funktionen zu machen, sind Dinge, die nur innerhalb von Member-Funktionen aufgerufen werden (müssen nicht außerhalb der Klasse sichtbar sein) und können gut mit den öffentlichen Mitgliedern der Klasse umgehen und / oder eine kleine Anzahl von Parametern.