Aggregation: Objekt in Aggregat ändern oder nicht?
-
Hallo,
ich habe eine Klasse die eine andere aggregiert. Also Klasse A hat einen member der vom Typ Klasse B ist.
Jetzt bildet Klasse A sozusagen meinen Hauptalgorithmus der ständig Methoden von Klasse B aufruft. Die ganzen Berechnungen finden also in B statt.
Jetzt habe ich einen Container (z.B. std::vector) auf dem die ganzen berechnungen stattfidnen sollen (oder ein teil davon).Ist es hier sauberer in Klasse A den container (member) anzulegen und dann über methodenaufrufe in B zu verändern (zurückzugeben)
-> siehe variante 1oder ist es sauberer in B einen memeber anzulegen und dann jeweils aus A nur die Veränderung z.B über Methodenaufrufe zu verändern? Hier muss das ergebniss halt mal am ende dann mal zurückgegeben werden.
-> siehe variante 2Welche der beiden varianten ist denn sauberer?
// ALLES PSEUDOCODE
VARIANTE 1
void A::hauptmethode() { std::vector *vec = new std::vector(10); // b ist vom Typ B b.foo(vec); ... } void B::foo(std::vector*& vec) { // mache was mit vec und verändere ihn }VARIANTE 2
void A::hauptmethode() { std::vector *erg; // b ist vom Typ B b.foo(); b.bar(); ... // rufe hier eine methode auf die einen ergebnisvector zurückgibt z.B. erg = b.erg(); } // B hat einen member std::vector *vec // der durch den konstruktor initialisiert wird void B::foo() { // mache was mit vec und verändere ihn } void B::bar() { // verändere vec wieder z:B. durch multiplikation mit einem anderen // vec2 } std::vector* B::erg() { // berechne ergebnis vector und gib zurück std::vector* erg = new std::vector(10); // mache mit erg was also berechne es return erg; }
-
mein Vorschlag wäre folgender
- Klasse A (Hauptalgo) als Member in B
- Klasse B beinhaltet den Vector, auf den die Berechnungen stattfinden sollen.
- Deine Algo-funktionen bekommen als Übergabeparameter den Vector, zum Beispiel per Referenz, falls dort direkt was geaendert werden soll.Vorteil der ganzen Sache ist, dass du die Klasse deines Hauptalgorithmus nicht staendig von Programm zu Programm abaendern musst.
-
BasicMan01 schrieb:
- Deine Algo-funktionen bekommen als Übergabeparameter den Vector, zum Beispiel per Referenz, falls dort direkt was geaendert werden soll.
Ich würde sogar noch weiter gehen, und keinen vector sondern nur iteratoren übergeben, welche man als template-Parameter übergeben kann. So kannst du dich komplett von vector lösen, und deinen Algorithmus allgemein implementieren.
Von welcher Art von Algorithmus sprechen wir denn? Kannst du evtl. auf eigenes Gebastel verzichten und einfach std::transform verwenden?
http://www.cplusplus.com/reference/algorithm/transform/
-
mein Vorschlag wäre folgender
- Klasse A (Hauptalgo) als Member in B
- Klasse B beinhaltet den Vector, auf den die Berechnungen stattfinden sollen.
- Deine Algo-funktionen bekommen als Übergabeparameter den Vector, zum Beispiel per Referenz, falls dort direkt was geaendert werden soll.Vorteil der ganzen Sache ist, dass du die Klasse deines Hauptalgorithmus nicht staendig von Programm zu Programm abaendern musst.
das verstehe ich nicht ganz - das würde ja alles umdrehen !? Wie kann ich denn dann in einer klasse C den hauptalgorithmus aufrufen wenn er selbst nur member ist !?
-
Wo kommt auf einmal eine Klasse C her
... die hast du dir doch ausgedachtin welchem Zusammenhang soll sie zu A oder B stehen?
Wird C von B vererbt?
Ist C eine komplett eigenständige Klasse die vielleicht auch A als Member benötigt, um auf die Algo-Funktionen zugreifen zu können?
-
Hmm...naja...also mein Algorithmus ist doch komplett sauber in einer eigenen Klasse:
class Algorithmus { public: void ersterSchritt() {} void zweiterSchritt() {} //... B b; };dieser algorthmus wird natürlich so niht laufen - ich muss ihn irgendwo z.B. in der main aufrufen oder in einer sonstigen Klasse.
Und jetzt will ich eben die ganzen rechnungen von Algorithmus nicht in Algorithmus sondern z.B. in einem Member Klasse B machen.
ich steh jetzt auf dem schlauch

-
Dann implementier doch in
Bentsprechend die Methoden, die nötig sind und ruf sie vonAlgorithmusauf. Wo genau ist denn da das Problem?Wie man Klassen und Funktionen dazu erstellt ist dir, nehme ich mal klar, oder?
-
Ja das hatte ich auch vor aber in meinem ersten post hatte ich ja gefragt
ob es sauberer ist den std::vector in Algorithmus zu halten und dann an B zu übergeben oder eben in B den std::vector halten und dort einfach über die methodenaufrufe zu verändern....
-
ich hab mal eben was zusammengepfuscht ohne jetzt mit Iteratoren zu handieren.
aber das kann man ja beliebig erweitern.class Algorithmus { public: void ersterSchritt(std::vector<int> &vec) {} void zweiterSchritt(std::vector<int> &vec) {} }; class B { private: Algorithmus algo; vector<int> vecDaten; public: void berechnen() { algo.ersterSchritt(vecDaten); } }; int main(int argc, char *argv[]) { B b; b.berechnen(); return 0; }
-
So kann man es machen.
Die Frage kann man aber imo nicht generell beantworten. Es kommt drauf an, wohin der vector eher gehört. Gehört er eher zuBoder zuAlgorithmus?Ich könnte mir z.B vorstellen, dass du verschiedene Implementierungen von
ersterSchrittundzweiterSchritthaben kannst und dann macht es schon Sinn, dass die Daten zu B gehören und nicht zuAlgorithmus, weil du dann die Verfahren on the fly ändern kannst ohne da irgendwie etwas rumkopieren zu müssen.
Wenn dervectorallerdings lediglich eine Art zwischenspeicher für das Endergebnis ist, dann könnte der schon auch in Algorithmus gehalten werden.Man kann sicher noch mehr ähnliche Beispiele finden, aber ich denke du verstehst, auf was ich hinaus will.
-
Hmm danke für das beispiel...ich frage mich nur - macht man das immer so? Also dass man eher von unten hoch gliedert?
-
AnfaengerNeu++ schrieb:
[...] macht man das immer so? [...]
Nein, das hängt immer vom Anwendungsfall ab. Wie drakon schon beschrieb.
Ich habe mich an deinem von gestern erstellten Thread orientierthttp://www.c-plusplus.net/forum/viewtopic-var-t-is-266924.html
dort heißt es:
AnfaengerNeu++ schrieb:
ich habe eine ganz einfache frage: Ich habe mehrere klassen die alle einen hauptalgorithmus darstellen. Alle diese klassen haben mehrere Methoden gemeinsam.
mehrere Methoden gemeinsam deutet darauf hin, dass man diese nicht ständig pro Klasse anpassen muss.

-
Für solche Sachen gibt es sogar ein eigenes Entwurfsmuster (falls der Algorithmus austauschbar sein soll): Schablonenmethode.