INFORMATIK I

Übung 10 : Klassen


6. Mai 2015


Daniel Hentzen
dhentzen@student.ethz.ch




Übung 9 : File I/O



Theorie





  • Klassen
    • Definition
    • Konstruktoren & Destruktoren
    • Operatoren
    • friends, this, const

Klassen


  • ähnlich zu den structs
  • nur in C++ (nicht in C)
  • bestehen aus : 
    • member Variablen
    • member Funktionen (= methods)
  • members sind entweder
    • private
    • public




Definition

 





Objektdeklaration


  • nach der Definition der Klasse ist sie als neuer Typ verfügbar
  • man kann jetzt Variablen dieses Typs erstellen : Objekte

Complex number1;
Complex number2;

  • wir können ausserdem die public member functions  aufrufen :  

number1.set(1,0);
number2.set(4.93,-1);


Member Funktionen implementieren


ausserhalb der Klasse : 

void Complex::set(double r, double i)
{
	real = r;
	imag = i;
}

Member Funktionen können auf private members der Klasse zugreifen

Header Files


  • Klasse normalerweise in 2 Teilen geschrieben :
    • Header file
      • complex.h
      • Definition der members

class Complex
{
private:
	double real;
	double imag;

public:
	void set(double r, double i);
};


  • Body file
    • complex.cpp
    • includes complex.h
    • Implementierung der member Funktionen

#include "complex.h"

void Complex::set(double r, double i);
{
	real = r;
	imag = i;
}

Konstruktor


  • Wie initialisiert man Objekte?
  • structs

Student stud = {"John", "Doe", 1324142}

  • bei Klassen nicht möglich : auf private members kann man von ausserhalb nicht zugreifen! 
  • Lösung : Konstruktoren


  • Konstruktor = Methode die bei der Deklaration eines Objekts aufgerufen wird.

  • Default-Konstruktor existiert immer : 

Complex c; //implizit
Complex d = Complex(); //explizit

  • mehrere, personalisierte Konstruktoren möglich

Eigene Konstruktoren


Implementieren :
Complex::Complex(double r, double i)
{
	real = r;
	imag = i;
}


  • Konstruktor = spezielle member Funktion, ohne return, gleicher Name wie Klasse
  • Der default-Konstruktor wird überschrieben!!!
  • --> neu definieren



Konstruktor aufrufen


Complex c1 = Complex(1.0,2.0);
Complex c2(1.0, 2.0);
Complex c1; //no longer valid

Destruktor


  • 2. spezielle member function
  • nur 1 Destruktor möglich
  • nur bei dynamischem Speicher !
  • gleicher Name wie Klasse, mit ~
  • kein return, keine Argumente
  • Objekte löschen, Speicher freimachen

Complex::~Complex()
{
	// destroy the world.
}

Aufruf


  • automatisch
    • bei delete[]
    • am Ende des scopes

  • explizit  :

Complex c;
...
c.~Complex();

Operatoren

  • Interaktion zwischen Objekten
  • Könnte so gelöst werden : 
Complex c(8.3, 2.4);
Complex d(0.5, 4.1);

//Member Funktionen, die die arithmetischen Operationen implementieren
c.add(d);
c.sub(d);
c.mult(d);
c.div(d);
  • besser wäre : 
Complex e;
e = c + d;
e = c - d;
e = c * d;
e = c / d;



Definition der Operatoren


  • Operatoren können definiert werden, wie Funktionen
  • mit const
  • linkes Objekt = aufrufendes Objekt




Aufruf

Complex a;
Complex b;

// Aufruf als Operator
Complex s1 = a + b;

// oder normal als Funktion
Complex s2 = a.operator+(b);

ACHTUNG : Linkes Objekt = aufrufendes Objekt (= *this) !!

const

Variablen : 
int j = 5, k = 6;
const int i = 1;
i = 2; // ERROR

const int *i = &j;
i = &k; //ERROR
*i = k; // ok
Funktionen : 
const Complex getSum(const Complex a) const; 

  • Rückgabewert konstant
  • Parameter konstant
  • Funktion konstant
    • member Variablen unverändert
    • kann nur const Methoden aufrufen

This


  • This
    • immer Pointer auf aufrufendes Objekt
    • Bsp :

const Stock & topval(const Stock &s) const;
// Prototyp, Funktion verändert Objekt nicht (const)!
const Stock & Stock::topval(const Stock &s) const
{
	if (s.total_val > total_val)
		return s;
	else 
		return *this; //aufrufendes Objekt
}top = stock1.topval(stock2);top = stock2.topval(stock1);

(total_val = this->totalval)



friend


  • erlaubt Zugang zu privaten Funktionen / Variablen
  • Funktionen, die nicht Mitgliedsfunktionen der Klasse sind, haben trotzdem Zugriff auf die private section
  • Prototyp der friend Funktion innerhalb der Klasse.




void myFunction(){...} //keine member Funktion!
class MyClass{...}; //keine member Klasse!

class Complex
{
public:
	friend void myFunction(); //Prototyp friend Funktion
	friend class MyClass; //friend Klasse
};
  • myFunction hat jetzt Zugang auf den private Bereich von Complex
  • alle member Funktionen von myClass haben auch Zugang

Beispiel : Operatoren


Complex c = Complex(3.0, 1.5);
Complex d = c * 2.3; // ok, d = c.operator*(2.3);
Complex e = 2.3 * c; // Problem!

linkes Objekt = aufrufendes Objekt
--> 2.3 ist keine Klasse !
--> keine entsprechende Operatormethode !

--> Wir brauchen eine Funktion ausserhalb der Klasse, die Zugang auf private hat!









Lösung


  • als friend in der Klasse deklarieren :
friend Complex operator*(double m, const Complex &c);

  • ausserhalb der Klasse implementieren :

Complex operator*(double m, const Complex &c)
{
	Complex result;
	result.real = m * c.real;
	result.imag = m * c.imag;

	return result;
}










Übung 10 : Klassen




Aufgabe 1 & 2 : Rationale Zahlen





Aufgabe 3 : Binomialkoeffizient



Aufgabe 4 : 

Kompilieren und Makefiles

Übung 10: Klassen

By Daniel Hentzen

Übung 10: Klassen

  • 825