2010-12-20 7 views
2

In meiner Freizeit habe ich Code, den ich für verschiedene Zwecke geschrieben habe, übernommen und in andere Sprachen übersetzt, nur um zu sehen, was da draußen ist. Momentan nehme ich einen Farbalgorithmus für die genetische Programmierung, der ursprünglich in Java geschrieben wurde, und versuche, ihn in C++ zu zwingen.Kompartimentierung und Design von Klassen in C++

Die willkürliche Datenstruktur, die ich für die Aufgabe verwende, hat ein paar Klassen. In Java war es für mich nicht so ein Problem, weil ich es eine Zeit lang ausgesetzt war. Die Graphenstruktur wurde nur einmal erstellt, und eine Colouring wurde zugewiesen. Die Colouring (speziell das Finden eines meist optimalen) war der eigentliche Sinn des Codes. Ich könnte eine Graph Klasse mit inneren Klassen haben wie Node und Edge, zum Beispiel, oder ich könnte ein Paket mit Klassen Graph, Node, Edge usw.

Der erste Fall über sich vielleicht leihen müssen gut meine Vorstellung von C++. In einer Hauptdatei * .cpp können einige Klassen Node, Graph, Edge definiert sein. Aber das scheint wirklich der Punkt von C++ zu fehlen, von dem, was ich sagen kann. Ich nehme nur, was ich in Java schrieb und erzwingen es in C++, Hinzufügen von Destruktoren wo angemessen und Objektverweise auf Zeiger drehen. Ich bin noch nicht Denken in C++. Unterteilen sich diese Klassen in separate * .cpp-Dateien? Sollten sie getrennt und dann als eine Bibliothek zusammengestellt werden, um sie im Hauptprogramm zu verwenden? Was ich wirklich brauche, sind einige gute Ressourcen oder erfundene Beispiele (oder sogar Faustregeln), um zu sagen, in welcher C++ - Programmierung welche verschiedenen Optionen existieren und wann es eine gute Idee ist, über das eine oder das andere nachzudenken?


EDIT: Ich wurde von @Pawel Zubrycki gebeten, einige Beispielcode zur Verfügung zu stellen. Ich werde das nicht tun, weil jede Komponente ziemlich trivial ist - sie hat im Allgemeinen einen Verweis auf die nächste Sache und einige Methoden zum Abrufen/Setzen. Ich werde es jedoch beschreiben.

Es ist im Wesentlichen eine Inzidenzliste. Es gibt einige unnötige Verwendung von Klassen mit der Bezeichnung ...Pointer - sie waren ein Produkt einer wörtlichen Übersetzung eines Diagramms, das zuerst verwendet wurde, um Inzidenzlisten für mich zu erklären.

Es gibt eine Container-Klasse, VertexList, die VertexPointer ein Kopfelement enthält, und Methoden, um neue hinzuzufügen VertexPointer Objekte (es zu dem Graphen hinzufügen, aber es nicht zu irgendwelchen anderen Knoten verbinden, ermöglichen die Suche nicht-zusammenhängende Graphen suchen), naive Suche nach Indizes auf Vertex Objekte usw. Jede VertexPointer hat eine Vertex Objekt, sowie eine VertexPointer next;, und all diese handlichen hasNext() Methoden, die Sie erwarten könnten. Ein Vertex hat auch ein zugehöriges ConnectionList

Das gleiche gilt für EdgeList dupliziert, EdgePointer und Edge, mit der Ausnahme, dass ein Edge mit zwei Connection Objekten zugeordnet ist.

ConnectionList und Connection: ConnectionListVertexList oder EdgeList imitieren, mit einer Connection head; und all diesen handlichen Methoden, die Sie könnten, wie addConnection() erwarten. Ein Connection hat eine Edge mit ihm verbunden sind, sowie einige Connection next;

Dies erlaubt uns, die angeschlossenen Komponenten von einem beliebigen Punkt in dem Diagramm leicht zu bekommen, und haben eine beliebige Anzahl von Verbindungen.


Es scheint ziemlich over-the-top kompliziert, aber die gleiche Funktionalität kann mit einigen LinkedList von Vertex Objekten dupliziert wird, ein LinkedList von Edge Objekten, und eine Reihe von LinkedList von Connection Objekten. Die LinkedList von Vertex Objects ermöglicht es uns, über alle Vertices zu iterieren, um erschöpfend nach Vertices zu suchen, und das Gleiche gilt für Kanten. Die Objekte von Connection ermöglichen es uns, schnell zu allen verbundenen Vertices zu gehen und beliebig viele Verbindungen in dem Graphen hinzuzufügen. Dieser Schritt in der Komplexität wurde hinzugefügt mit der Komplexität zu bewältigen, eine bestimmte Färbung eines Graphen (gewichtete Kanten, schnelle Traversal von lokalen Subgraphen, etc.) Auswertung

+0

Diese Frage ist besser geeignet für programmers.stackexchange.com. –

+0

Siehe http://stackoverflow.com/questions/997924/c-best-practices – Simone

+5

@Gunner - Ich glaube, dass diese Frage für beide Seiten geeignet ist. Obwohl es unter "Architecture.StackExchange.com" (und vielleicht besser) unter "Architecture" und "Design Patterns" passt, ist dies ein spezielles Programmierproblem, nach dem ich die Antwort für eine bestimmte Sprache suche. Ich frage nicht, was OOP ist, oder über bestimmte Designmuster in einer Sprache agnostisch. @Simone - Das ist eine interessante Lektüre, aber die Links dort adressieren meine Frage nicht. Ich denke aber, dass ich das auch in meiner Freizeit lesen werde. Vielen Dank. – JBirch

Antwort

2

Wenn Sie Klassen wie Node, Graph und Edge und ihrer Implementierung ist nicht zu groß, es macht durchaus Sinn, sie in ein und derselben CPP-Datei zu definieren. Schließlich sollen sie zusammen verwendet werden.

In C++ wird ein solches Paket als Komponente bezeichnet. Normalerweise ist es sinnvoller, in Komponenten als in Klassen zu denken, da C++ nicht nur eine OOP-Sprache ist und Klassen nicht immer die bevorzugte Methode sind.

Wenn Sie mehr über die bevorzugte Methode zum Organisieren von Code in C++ erfahren möchten, empfehle ich Large Scale C++ Software Design.

BTW: Eine Bibliothek aus diesen Klassen zu machen scheint wirklich übertrieben.

+0

Um etwas expliziter zu sein, ist die verwendete Datenstruktur eine Inzidenzliste und etwas komplizierter als nur 'Node',' Edge', etc. Die Datenstruktur selbst ist wahrscheinlich nicht einer Bibliothek würdig, aber es gibt eine Möglichkeit, dort viel Funktionalität bezüglich Suchen zu implementieren und was ich auch nicht zusätzlich angeben darf. Ist es die Komplexität der Komponente oder der Umfang der Funktionalität, die bestimmen sollte, wann Komponenten gegenüber Bibliotheken betrachtet werden? Danke auch für die Referenz - ich habe das zu meiner To Read Liste hinzugefügt. – JBirch

+0

Es ist eine sehr offene Frage. Aber eine Idee könnte auch Boost.Graph sein. Es ist kompliziert, wird aber im Allgemeinen als sehr gut konzipiert angesehen. Hier ist eine Beschreibung seiner Adjazenzliste Implementierung: http://www.boost.org/doc/libs/1_42_0/libs/graph/doc/adjacency_list.html –

+0

... und über Komponenten im Vergleich zu Bibliotheken: Dies ist nicht wirklich ein Sache der Code-Organisation, so viel wie Code-Verteilung. Schließlich enthalten Bibliotheken Komponenten. –