Mitgliedsfunktion vs. Nichtmitgliedsfunktion?

7

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?

    
rlbond 03.04.2009, 22:07
quelle

6 Antworten

11

Wann es zu einer Mitgliedsfunktion wird:

  • wenn die Funktion logisch mit der Klasse gekoppelt ist (wie in Ihrem Labyrinth-Connectedness-Beispiel)
  • Wenn die Funktion auf private oder geschützte Mitglieder zugreifen muss, ist es besser, sie zum Mitglied als zu einem Freund zu machen.

Wann es eine eigenständige Funktion machen soll

  • wenn es sich um eine generische Funktion handelt, die so templatisiert werden kann, dass sie natürlich auch in anderen Klassen funktioniert (siehe die Kopfzeile & lt; Algorithmen & gt; für ein gutes Beispiel)
Mr Fooz 03.04.2009, 22:14
quelle
13

Herb Sutter sagt: "Wir wollen sie zu Nichtmitgliedsfreunden machen, wenn es vernünftigerweise möglich ist", und er ist schlauer als ich.

Ссылка

    
Mark Ransom 03.04.2009 22:46
quelle
12

Nun, es gibt Argumente für beide.

zugunsten von Nichtmitgliedsfunktionen:

  • Es bietet bessere Kapselung
  • Es ermöglicht eine bessere Codewiederverwendung (std :: find kann für any Containertyp wiederverwendet werden, da es eine freie Funktion ist. Wenn es ein Member gewesen wäre, müsste jeder Container seinen eigenen definieren)
  • Es erleichtert viele generische Programmiertricks. ( 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:

  • Es ist bekannt. Java und C # erfordern dies, und in den Augen vieler Programmierer sind Elementfunktionen gleichbedeutend mit OOP.

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.

    
jalf 03.04.2009 23:35
quelle
4

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.

    
Stefano Borini 03.04.2009 22:13
quelle
3

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.

    
dirkgently 03.04.2009 22:10
quelle
0

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.

    
T.E.D. 03.04.2009 22:45
quelle

Tags und Links