Fragen zur Programmstruktur (Methodentyp und Ergebnisberechnung)



  • Ich will die Variable myVar berechnen und in der Klasse "Speichern" ablegen.

    Ich habe folgenden Programmaufbau:

    - Eine Klasse "Berechnung", hier findet die Berechnung statt
    - Eine Klasse, in der das Ergebnis gespeichert werden soll
    - Eine Methode der Klasse "Berechnung", in der die Berechnung stattfindet
    - einen Setter, mit dem die Variable aus der Berechnung in der Klasse Ergebnis gespeichert werden soll
    - den Aufruf

    Folgende Fragen dazu:
    - Welchen Typ soll CalculateMyVar geschickterweise erhalten? Bool oder etwas anderes?
    - an welcher Stelle ruft man am besten SetMyDouble(myVar) auf? In der Berechnungsmethode oder in der main?
    - Ist es richtig, Referenzen an CalculateMyVar zu übergeben oder sollte man das anders lösen?

    Danke für die Hilfe.

    class Berechnung
    {	
    	bool CalculateMyVar(float &para1, float &para2);
    
    };
    
    class Speichern
    {
    	double myVar;
    
    	void setMyDouble(const double myVar)
    	{
    		this->myVar = myVar;
    	}
    
    };
    
    bool Berechnung::CalculateMyVar(float &para1, float &para2)
    {
    	para1=...
    	para2=...
    
    	myVar= ...
    
            Speichern.B;
            B.SetMyDouble(myVar); 
    
    	return true;
    }
    
    int main(int argc, char *argv[])
    {
    	float para1, para2;
    
    	Berechnung A
    	A.CalculateMyVar(para1,para2);
    }
    

  • Mod

    Deine Problembeschreibung ist zu abstrakt, als das man hier tolle konkrete Tipps geben könnte. Sagen wir mal allgemein: Nicht alles muss eine Klasse sein.

    Wenn das Problem wirklich so wie hier beschaffen wäre, dann wäre die ganze Berechnung keine Klasse, sondern nur eine Funktion. Ich vermute mal, dein konkretes Problem sieht aber anders aus, da ist dann auch sicherlich ein anderes Design gefragt.

    Allgemeine Tipps:
    -Weil es so wichtig ist, noch einmal wiederholt: Nicht alles muss eine Klasse sein.
    -Klassen stellen Objekte unserer Vorstellungskraft dar, keine Tätigkeiten. "Speichern" ist nichts, was man mit einer Klasse modellieren würde. Das Konzept eines "Speichers" würde schon eher passen. Entsprechend würde sich dann die Gestaltung einer solchen Klasse ändern. Ebenso ist "Berechnung" sehr grenzwertig als etwas, das in einer Klasse modelliert werden soll. Das Konzept einer Berechnung gibt es nämlich schon fertig in C++, das nennt sich "Funktion".
    -Eine Instanz einer Klasse sollte nach ihrer Erstellung (Konstruktoraufruf) bereit sein zum Einsatz. Klassen, bei denen der Anwender etwas falsch machen kann, zum Beispiel weil er erst einen Setter aufrufen muss, bevor er eine Berechnungsmethode aufruft (das könnte er nämlich vergessen), sind falsch gestaltet.
    -Klassen sollten unabhängig voneinander sein, wenn das, was sie modellieren, unabhängig voneinander ist. Wenn bei der "Berechnung" nicht essentiell ist, dass das Ergebnis in einem "Speicher" landet, dann sollte sie ihr Ergebnis auch nur an den Anwendungscode zurück geben und diesen entscheiden lassen, was damit zu tun ist. Wenn für eine "Berechnung" ein "Speicher" notwendig sein sollte, dann gilt dies natürlich nicht, dann muss der "Berechnung" eben ein "Speicher" bekannt sein, damit sie funktioniert.



  • Die Wortwahl für die Klassen war etwas unglücklich.
    Damit war einfach nur gemeint, dass die eine Klasse die Methode zur Berechnung der Variable enthält, nicht dass sie generell für Berechnung zuständig ist. Ich will die dort errechnete Variable auf die Variable einer anderen Klasse übertragen.

    Welchen Methodentyp soll bool Berechnung::CalculateMyVar(float &para1, float &para2) am besten erhalten?
    Arbeite ich hier generell besser mit Referenzen oder mit Pointern?



  • Sunset schrieb:

    Welchen Methodentyp soll bool Berechnung::CalculateMyVar(float &para1, float &para2) am besten erhalten?
    Arbeite ich hier generell besser mit Referenzen oder mit Pointern?

    Am besten mit Werten.
    Willst Du wirklich para1 und para2 verändern?

    Das offensichtlichste ist doch:

    double calculate(float, float);
    

    Oder ein Konstruktor in Speichern mit 2 float Argumenten.

    Ich finde das alles zu abstrakt um helfen zu koennen.



  • Solange die Parameter (falls es primitive Datentypen sind) während der Berechnung nicht verändert werden solltest du sie by Value übergeben.



  • Sunset schrieb:

    Ich will die dort errechnete Variable auf die Variable einer anderen Klasse übertragen.

    Im allgemeinen werden "Variablen" eines anderen Objekts geändert. Dazu muss man das andere Objekt natürlich kennen. Klassenvariablen (=statisch) werden eher selten für Berechnungen benutzt. Ich habe den Eindruck, dass die dieses Konzept nicht klar ist. In CalculateMyVar ein Objekt zu erzeugen, den Wert zu setzen und es dann gleich wieder zu verwerfen ist offensichtlich nicht sinnvoll.



  • @Sunset

    > - Welchen Typ soll CalculateMyVar geschickterweise erhalten? Bool oder etwas anderes?

    Welchen "Typ" Funktionen haben ergibt sich meist mehr oder weniger direkt daraus was sie tun. Was tut deine Funktion?
    Und wie kommst du auf bool ?
    Fehlerbehandlung macht man in C++ "idiomatischerweise" mit Exceptions - d.h. dazu braucht man gar keinen Returnwert.

    > - an welcher Stelle ruft man am besten SetMyDouble(myVar) auf? In der Berechnungsmethode oder in der main?

    Auf jeden Fall nicht innerhalb einer Funktion die irgendwas berechnet.
    Stichwörter:
    * Single-Responsibility-Principle
    * Separation of Concerns
    Und wie SeppJ schon gesagt hat: Nicht alles muss eine Klasse sein.

    > - Ist es richtig, Referenzen an CalculateMyVar zu übergeben oder sollte man das anders lösen?

    Wurde auch schon beantwortet: Parameter übergibst du am besten direkt, by Value. Bei teuer zu kopierenden Sachen ( std::string , std::vector , ...) kann man schön "const Referenzen" verwenden, aber bei int , double etc. immer by Value.
    Falls du die Referenzen als Output-Parameter verwendest, dann wäre vermutlich die bessere Alternative dem Wertepaar einen "Namen" zu verpassen. Indem du eine kleine struct definierst die die beiden Werte enthält, und dann diese struct zurückgibst.


Log in to reply