SimpleStat mit Methoden

Ähnliche Dokumente
Ziel, Inhalt. Programmieren in C++ Wir lernen wie man Funktionen oder Klassen einmal schreibt, so dass sie für verschiedene Datentypen verwendbar sind

Methoden. von Objekten definiert werden, Methoden,, Zugriffsmethoden und Read-Only

Objektorientierung: Klassen und Objekte

Objektorientierung Grundlagen

Programmieren II Klassen. Programmieren II Klassen. Programmieren II Klassen. Programmieren II Klassen. Zur Erinnerung.

Überladen von Operatoren

Alltagsnotizen eines Softwareentwicklers

DAP2-Programmierpraktikum Einführung in C++ (Teil 1)

10. Klassen. Prof. Dr. Markus Gross Informatik I für D-ITET (WS 03/04)

Die abgeleiteten Klassen Kreis und Viereck erben die Elemente des Basisklasse und verfügen über zusätzliche Eigenschaften (Seitenlänge,

Hochschule München, FK 03 SS Masterstudiengang Technische Berechnung und Simulation. Programmierung von CAx-Systemen Teil 1

C++ - Eine Ubersicht fur Java-Programmierer

Aufbau von Klassen. class punkt {...

Programmieren II Vererbung. Programmieren II Vererbung. Programmieren II Vererbung. Programmieren II Vererbung. Einleitende Bemerkungen

Grundlagen. Kapitel 1

C++ - Operatoren. Eigene Klassen mit neuen Funktionen

Vorkurs C++ Programmierung

Übung 9. Quellcode Strukturieren Rekursive Datenstrukturen Uebung 9

Einführung in die Programmierung mit C++

In der Computersprache C ist die Standardmethode zur Behandlung von Matrizen durch

Von Java nach C++ Dr. Frank Weichert Lehrstuhl Informatik VII Technische Universität Dortmund

Von Java nach C++ Frank Weichert, Heinrich Müller Informatik VII Universität Dortmund

Praktikum Betriebssysteme 1. Aufgabe (1)

Elementare Datentypen in C++

1.2 Attribute und Methoden Aufbau einer Java-Klasse:

3. Semester : 1. Prüfung

Verwendung von Klassen in C++

Programmieren in C++ Überladen von Methoden und Operatoren

Objektorientiertes Programmieren für Ingenieure

OOP und Angewandte Mathematik. Eine Einführung in die Anwendung objektorientierter Konzepte in der angewandten Mathematik

Betriebssysteme: Konzepte, Dienste, Schnittstellen (Betriebssysteme und betriebssystemnahe Programmierung)

13. Vererbung. Prof. Dr. François E. Cellier Informatik I für D-ITET (HS 2012)

Programmieren in C. Macros, Funktionen und modulare Programmstruktur. Prof. Dr. Nikolaus Wulff

Klausurvorbereitung Lösung

Einstieg in die Informatik mit Java

Einführung in den Einsatz von Objekt-Orientierung mit C++ I

Der C++ Crashkurs v1.0

Prof. W. Henrich Seite 1

FB Informatik. Fehler. Testplan

Einführung in C++ mit Microsoft VS

Unterprogramme. Funktionen. Bedeutung von Funktionen in C++ Definition einer Funktion. Definition einer Prozedur

Objektorientierte Programmierung mit C++ Vector und List

Hochschule Darmstadt Informatik-Praktikum (INF 1) WS 2014/2015 Wirtschaftsingenieur Bachelor 4. Aufgabe Datenstruktur, Dateieingabe und -ausgabe

Programmieren in Java

Übung HP Beispielaufgaben 3

Zählen von Objekten einer bestimmten Klasse

JAVA - Methoden - Rekursion

Assoziative Container in C++ Christian Poulter

12. Vererbung. Prof. Dr. Markus Gross Informatik I für D-ITET (WS 03/04)

Kapitel 8. Programmierkurs. Methoden. 8.1 Methoden

11. Klassen. Prof. Dr. François E. Cellier Informatik I für D-ITET (HS 2012)

Objektorientierte Programmierung

Prüfung in PROGRAMMIEREN 3 WS 2006/07

Vergleich verschiedener OO-Programmiersprachen

C vs. C++ Sebastian Meyer. Proseminar C - Grundlagen und Konzepte. Universität Hamburg

Einführung in die C++ Programmierung für Ingenieure

7. Objektorientierte Softwareentwicklung/3. Informatik II für Verkehrsingenieure

Es ist für die Lösung der Programmieraufgabe nicht nötig, den mathematischen Hintergrund zu verstehen, es kann aber beim Verständnis helfen.

Repetitorium Informatik (Java)

Objektbasierte Entwicklung

Informationsverarbeitung im Bauwesen

Klausur C++ #1 Jahr: 2001; Dozent: Dipl.Ing. Sorber

Zusammengesetzte Datentypen -- Arrays und Strukturen

Programmierkurs C++ Abstrakte Klassen und Methoden

2. Semester, 2. Prüfung, Lösung

Software Engineering Klassendiagramme Einführung

Einführung in die Programmierung 1

Hochschule Darmstadt Informatik-Praktikum (INF 1) WS 2015/2016 Wirtschaftsingenieur Bachelor 5. Aufgabe Datenstruktur, Dateieingabe und -ausgabe

C++ - Einführung in die Programmiersprache Objektorientierte Programmierung

Teil 6: Klassenkonzept. Prof. Dr. Herbert Fischer Fachhochschule Deggendorf Prof. Dr. Manfred Beham Fachhochschule Amberg-Weiden

Angewandte Mathematik und Programmierung

Praxisorientierte Einführung in C++ Lektion: "Die Compiler-Chain (Vom Quellcode zum ausführbaren Programm)"

Fakultät Angewandte Informatik Lehrprofessur für Informatik

5.5.8 Öffentliche und private Eigenschaften

Eine Klasse beschreibt Objekte mit gleichen Attributen und Methoden.

C++ Idiome. C++ Idiome. Detlef Wilkening C++ User-Treffen Aachen am

Javakurs für Anfänger

C++ - Funktionen und mehr. Kerstin Gößner und Ralf Wondratschek

01. Grundprinzipien der Vererbung

5.4 Klassen und Objekte

Funktionen Häufig müssen bestimmte Operationen in einem Programm mehrmals ausgeführt werden. Schlechte Lösung: Gute Lösung:

Pass by Value Pass by Reference Defaults, Overloading, variable Parameteranzahl

1. Vom Sourcecode zum Programm

C++ Kurs Teil 1. Architektur, Anwendungsspektrum, primitive Datentypen, Funktionsaufrufe, Referenzen, Klassen

5. Elementare Befehle und Struktogramme

Angewandte Mathematik und Programmierung

Klassen mit Instanzmethoden

Java: Vererbung. Teil 3: super()

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 18

JAVA - Methoden

Hochschule Darmstadt Informatik-Praktikum WS 2016/2017 WIng Bachelor 4. Aufgabenblatt Modularisierung, Funktionen, Unterprogramme

C++-Zusammenfassung. H. Schaudt. August 18, 2005

magnum C++ WALTER SAUMWEBER kompakt komplett kompetent

Java Vererbung. Inhalt

Transkript:

SimpleStat mit Methoden Als Ausgangspunkt nehmen wir folgende Definition (Version 1) von SimpleStat: double sum2; -Quadrate Dieser Objekttyp verfügt über keine Methoden und alle Datenattribute sind public. Warum ist das ein Problem? In einem Anwendungsprogramm steht dann z.b. : SimpleStat stat; if (stat.n = 10) // Fehler! Es sollte heißen if (stat.n == 10) Hier wird der Stichprobenzähler versehentlich umgesetzt und die Statistik liefert völlig falsche Werte. Verhindern lässt sich das nur dadurch, dass man die Datenattribute macht (Version 2): double sum2; -Quadrate Genau denselben Effekt hätte man erzielt, wenn man das Schlüsselwort struct durch class ersetzt. Allerdings kann jetzt niemand mehr mit der Version 2 arbeiten, weil NICHTS darauf zugreifen darf. Man muss jetzt Objektmethoden oder befreundete Funktionen definieren, die auf die Attribute zugreifen dürfen. Hier genügt es, eine Stichprobe zu verarbeiten und die statistische Endauswertung auszugeben. Wir haben dazu bisher 2 Funktionen geschrieben (eine davon ist der Streamausgabe-Operator): void push_back(simplestat& s, double x) { ++(s.n);... ostream& operator<<(ostream& out, const SimpleStat& s)

{ cout << "Statistische Auswertung: " << s.title << '\n'; return out; Am einfachsten macht man diese 2 Funktionen zu Freunden (Version 3): double sum2; -Quadrate friend void push_back(simplestat&, double); C++ beschwert sich jetzt noch über die fehlerhafte Instanzierung: SimpleStat daten{"double Zahlenreihe", 0, 0., 0. Wenn ein Objekt private Attribute besitzt, dann kann man diese nicht mehr ohne Konstruktoren initialisiieren. Eine Liste in geschwungenen Klammern mit allen Attributwerten reicht dann nicht mehr. Wir schreiben also einen Konstruktor, der den Titel setzt. Alle übrigen Werte sind ohnehin 0 oder 0. Der Konstruktor muss, damit man ihn überhaupt verwenden darf, public sein. Hier eine einfache Version mit Initialisierungsliste innerhalb der Objektdefinition (Version 4): SimpleStat(string text) : title{text, n{, sum{, sum2{ { double sum2; -Quadrate friend void push_back(simplestat&, double);

n{ oben bedeutet, dass n als Pod mit dem Defaultwert initialisiert wird (dieser ist 0 bzw. 0. für Gleitkommatypen). Es ist üblich (es gibt aber keinen zwingenden Grund dafür!), größere Objekte eher als class statt als struct zu definieren. SimpleStat(string text) : title{text, n{, sum{, sum2{ { double sum2; -Quadrate friend void push_back(simplestat&, double); Statt Freund-Funktionen kann man auch Methoden einsetzen. Es ändert sich die Übergabe des Referent-Elements: Aus der Funktion void push_back(simplestat& stat, double x); wird die Methode (diese muss jetzt public sein!) void push_back(double x); Die Streamausgabe kann zu keiner Methode umgeschrieben werden, da das 1. Argument der Stream ist und nicht die SimpleStat-Instanz. Es ist auch üblich (guter Stil), alle Methoden des Objekts (auch die Konstruktoren) außerhalb der Objektdefinition zu programmieren (Version 5): SimpleStat(string); void push_back(double); double sum2; -Quadrate SimpleStat::SimpleStat(string text) : title{text, n{, sum{, sum2{ { void SimpleStat::push_back(double x) { ++n;

sum += x; sum2 += x*x; Der Aufruf muss noch angepasst werden. Aus push_back(daten, x); wird daten.push_back(x); Damit wäre man eigentlich schon fertig. Viele Objekte haben eine befreundete Streamausgabe. Ich habe aber mit der Statistik-Klasse noch etwas anderes vor und deshalb möchte ich die Ausgabe ändern. Ich erledige diese durch eine neue public Objektmethode void print(ostream& out)const Die Streamausgabe ruft dann lediglich diese Objektmethode auf und braucht daher selbst keinen Zugriff mehr auf die privaten Objekt-Attribute. Damit kann man auch diese friend- Deklaration löschen (Version 6): SimpleStat(string); void push_back(double); void print(ostream&) const; double sum2; -Quadrate ostream& operator<<(ostream& out, const SimpleStat& stat) { stat.print(out); return out; Man schreibt noch die alte Streamausgabe zur print-methode um: void SimpleStat::print(ostream& out) const { out << "Statistische Auswertung: " << title << '\n'; SimpleStat ist bereits jetzt ein nützliches Tool zur statistischen Messwert-Analyse. Um die Wiederverwertung zu erleichtern, extrahiert man den Objektcode in 2 separate Dateien: Eine Headerdatei SimpleStat.h (nur die Objektdefinition und die Deklarationen der Utility-Funktionen), eine Codedatei SimpleStat.cpp. Das Anwendungsprogramm

inkludiert den Header und beim Kompilieren gibt man die Codedatei mit an. Die Anwendung anwendung.cpp: #include "SimpleStat.h" SimpleStat daten{"double Zahlenreihe" for (double x; cin >> x;) daten.push_back(x); cout << daten; Die Headerdatei SimpleStat.h: #ifndef SIMPLESTAT_H #define SIMPLESTAT_H // protect against multiple Inclusions #include <string> #include <iostream> SimpleStat(std::string); void push_back(double); void print(std::ostream&) const; std:: double sum2; std::ostream& operator<<(std::ostream&, const SimpleStat&); #endif // #ifndef SIMPLESTAT_H Die Headerdatei muss alles inkludieren, was sie selbst benötigt (iostream, string). Auch ist es schlechter Stil, in Headerdateien die using namespace std; Anweisung zu verwenden, weshalb man hier die benötigten std:: schreiben muss. Erklärung: Ein Anwender von SimpleStat möchte gerne selbst entscheiden, ob er diese using- Anweisung verwenden will oder nicht. Es kommt nicht gut an, wenn eine Headerdatei, die man inkludieren muss, diese Entscheidung trifft. Auch sollte man einen Schutz gegen mehrmaliges Inkludieren des Headers vorsehen (s.o.). Den C++-Code der Methoden und der Streamausgabe packt man in SimpleStat.cpp.

Diese inkludiert SimpleStat.h und implementiert nur mehr den fehlenden Code der Methoden und der Streamausgabe. Eine kleine Unterlassung in der Ausgabe habe ich auch noch behoben. Selbstverständlich darf man hier die using-anweisung wieder verwenden, wenn man möchte, da diese Datei nirgends inkludiert wird: #include <cmath> #include "SimpleStat.h" using namespace std; SimpleStat::SimpleStat(string text) : title{text, n{, sum{, sum2{ { void SimpleStat::push_back(double x) { ++n; sum += x; sum2 += x*x; void SimpleStat::print(ostream& out) const { out << "Statistische Auswertung: " << title << '\n'; out << "Anzahl der Stichproben: " << n << '\n'; if (n == 0) return; auto mw = sum/n; out << "Mittelwert der Daten: " << mw << '\n'; if (n == 1) return; auto sa = (sum2 - n*mw*mw)/(n-1); out << "Standardabweichung: " << sa << '\n'; out << "Streuung: " << sqrt(sa) << '\n'; ostream& operator<<(ostream& out, const SimpleStat& stat) { stat.print(out); return out;