18
Einführung in objektorientiertes Pro- grammieren in C++ Karl Gmeiner 2015

Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

  • Upload
    others

  • View
    11

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Pro-grammieren in C++Karl Gmeiner

2015

Page 2: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

1 Programmierparadigmen

• Programmieren = Problemstellung in einem Computerprogramm umsetzen.

– Problemstellung wird in Einheiten untergliedert.– Programmierparadigma: Art der Einheit = Grundlegende Art, wie programmiert wird.

• Einige Paradigmen:

– Imperatives Programmieren

* Prozedurales Programmieren (C)* Objektorientieres Programmieren (Java, C++)

– Deklaratives Programmieren

* Funktionales Programmieren (OCaml)* Logisches Programmieren (tw. SQL)

• Imperatives strukturiertes Programmieren: Programmfluss durch vorgegebene Konstrukte

– Sequenzen, Iterationen, Bedingungen, Abstraktionen

2 Objektorientiertes Programmieren

• Gliederung des Programmes in Objekte

2.1 Objekte

• Haben Eigenschaften

– Bestehen selbst aus weiteren Objekten

• Haben ein Verhalten

– Kommunizieren mit anderen Objekten

3 Objekt Pluto

• Eigenschaften:

– Name: “Pluto”

• Verhalten:

– Pluto kann bellen– Sieht Pluto einen anderen Hund, so wedelt er mit dem Schwanz

4 Objekt Idefix

• Eigenschaften:

– Name: “Idefix”

• Verhalten:

– Idefix kann bellen– Sieht Idexfix einen anderen Hund, so wedelt er mit dem Schwanz

1

Page 3: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

Figure 1: Pluto

5 Allgemein Hunde

• Eigenschaften:

– Hunde haben Namen

• Verhalten:

– Hunde können bellen– Sehen Hunde einen anderen Hund, wedeln sie mit dem Schwanz

2

Page 4: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

Figure 2: Idefix

3

Page 5: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

4

Page 6: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

5

Page 7: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

5.1 Was ist der Unterschied zwischen “Hund” und “Pluto”?

• Hund = Beschreibung einer Art (“Klassifikation”)• Pluto ist eine Instanz der Klasse Hund.• Beschreibung von “Hund” erklärt, wie sich einzelne Hunde verhalten und welche Eigen-

schaften sie haben.

6 Klassen

• Objekte werden in vielen Programmiersprachen durch eine entsprechende Klassifikation (=Klasse) beschrieben.

– Beispiele: C++, Java, C#, . . .

• Sichtbarkeiten

– Implementierung von Verhalten sollte versteckt sein (Austauschbarkeit)– Eigenschaften sollten nicht direkt manipuliert werden können (Data-Hiding)

6

Page 8: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

7 Dog-Klasse (1. Entwurf)

// dog.h

class Dog{public:

void talk(); // Methodevoid meet(Dog other); // Methodestring name; // Membervariablebool tailWagging; // Membervariable

}

• VORSICHT: Code hat VIELE Probleme!

8 Implementierung

// dog.cppvoid Dog::talk() {

cout << name << " says wuff" << endl;}

void Dog::meet(Dog other) {this->tailWagging = true;other.tailWagging = true;cout << name << " and " << other.name

<< " wag their tails" << endl;}

Innerhalb eines Objekts ist this ein Pointer (daher ->) auf das Objekt.

9 Verwenden von Objekten

// main.cppint main() {

Dog pluto;Dog odie;pluto.name = "Pluto";odie.name = "Odie";pluto.talk();// does 'Dog::talk();' work?

odie.talk();pluto.meet(odie);

pluto.tailWagging = false;}

7

Page 9: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

10 Funktionsaufrufe mit Objekten - Call-by-value

• Call-by-value

void changeName(Dog d) {d.name = "odie";

}

int main() {Dog pluto;pluto.name = "pluto";changeName(pluto);cout << pluto.name << endl; // Ausgabe?return 0;

}

11 Funktionsaufruf mit Objekten - Call-by-reference

void changeName(Dog &d) {d.name = "odie";

}

int main() {Dog pluto;pluto.name = "pluto";changeName(pluto);cout << pluto.name << endl; // Ausgabe?return 0;

}

• Referenz mit const: Objekt kann nicht geändert werden.• Vorsicht: C# und Java benutzen immer Call-by-reference!

– Grund: Objekte können gross werden– Kopieren kostet viel Zeit.

12 Data-Hiding

• Entscheidungsfreiheit: Es ist die Entscheidung des Hundes, ob er mit dem Schwanz wedeltoder nicht!

• tailWagging sollte daher nicht nicht von aussen gesetzt werden können.• Gleiches für name

13 Dog-Klasse (2. Entwurf)

// dog.hclass Dog{private:

8

Page 10: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

string name;bool tailWagging;

public:void talk();void meet(Dog &other);

}

14 Jetzt brauchen wir Getter und Setter, oder?

15 Getter and Setter are evil! (c) Karl Gmeiner

15.1 Warum objektorientiertes Programmieren?

• Objekte ergänzen reine Datenpakete (structs) um Verhalten, welches die Daten im Objektmanipuliert

• Daten werden von aussen geschützt.

– Zuverlässigkeit und Austauschbarkeit (Beispiel: Array in Objekt kann durch Liste ersetztwerden)

– Grundsatz: Die Klasse weiss immer noch am besten, wie man mit den Daten darinumgeht.

• Zusätzliche Abstraktionsebene entspricht Erfahrung in echter Welt

Verwenden von Getter und Setter = Degradieren einer Klasse zu einem reinen Datenpaket mitkomplexer Syntax.

16 XY sagte, wir brauchen Getter und Setter.

Ok, dann ist das aber kein Objekt sondern ein Datenpaket.

16.1 Aber manchmal brauche ich doch zumindest ein get?

• Ja. Und?• Grundsatz: Wenn ich es nicht brauche, sollte ich es nicht machen.• “Feature” “Generate Getters and Setters” ist wirklich böse und reduziert Wartbarkeit des

Codes.

16.2 Warum machen es dann viele?

Weil viele, die heute Programmieren unterrichten, mit structs gross geworden sind und diesegewohnt sind.

16.3 Ist jemand, der immer Getter und Setter erstellt, ein schlechter Pro-grammierer?

Nein. Er programmiert nur in einem nicht-objektorientieren Stil.

9

Page 11: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

Figure 3: Getter, Setter

10

Page 12: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

17 private-Sichtbarkeit

• Wie greift meet nun auf die Member von other zu?

– Kein Problem. private bezieht sich auf Klasse.– Wie schon gesagt: Die Klasse weiss, wie sie mit ihren Instanzen umgeht!

void Dog::meet(Dog other) {tailWagging = true;

other.tailWagging = true;cout << name << " and " << other.name

<< " wag their tails" << endl;// Zugriff auf others private member ist kein Problem,// weil other eine Instanz von Dog ist.

}

MAN BRAUCHT KEINE get-METHODE UM AUF MEMBERVARIABLEN ANDERER INSTANZENEINER KLASSE INNERHALB DER KLASSE ZUZUGREIFEN!

18 Konstruktoren

• Real world: Wann bekommt ein Hund einen Namen?

– Bei der Geburt.

• Bei Objekten spezielle Methode in Klassen zur Erzeugung von Objekten

// dog.hclass Dog {public:

Dog(string n); // constructor (ctor)

19 Implementierung ctor

• Setzen von Membervariablen

– Entweder im Block– oder davor

// dog.cppDog::Dog(string n) {

name = n;cout << "creating dog " << n << endl;

}

// dog.cppDog::Dog(string n) : name(n) {

cout << "creating dog " << n << endl;}

11

Page 13: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

20 Aufruf von Konstruktor

Direkt durch Angabe der Parameter oder mit “=”.

int main() {// Dog dog; not possibleDog pluto("pluto");Dog odie = string("odie");// same as Dog odie(string("odie"));!

// Let's create a twin of pluto:Dog anotherDogNamedPluto = pluto;// Hm, according to what we said above// for odie, this is the same as// Dog anotherDogNamedPluto(pluto);

// But what ctor was called here?return 0;

}

21 Copy-Konstruktor

• C++ erzeugt einige Konstruktoren und Methoden implizit

– Z.B. den Copy-Konstruktor: Dog(const Dog &dog)– Implizit Zuweisung aller Member-Variablen– Durch Explizit-Machen kann Default (Zuweisung aller Member-Variablen) geändert

werden.

// dog.hclass Dog {

/* ... */Dog(const Dog &dog);/* ... */

}

// dog.cppDog::Dog(const Dog &dog) : name(dog.name) {

cout << "creating a twin of " << name << endl;}

22 Destruktoren

• Gegenstück zum Konstruktor: Destruktor

– Wird aufgerufen, wenn Objekt zerstört wird und Speicher freigegeben werden soll

// dog.hclass Dog {public:

/* ... */

12

Page 14: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

~Dog(); // destructor (dtor)

// dog.cppDog::~Dog() {

cout << "destroying " << name << " :(" << endl;}

23 Aufruf von Destruktor am Ende des Gültigkeitsbereich

int main() {for(int i = 0; i < 3; ++i) {

Dog pluto("pluto no " + i);pluto.talk();

}return 0;

}

24 Komplexes Beispiel

// main.cppDog makeBarkAndReturn(Dog dog) {

dog.talk();return dog;

}

int main() {Dog pluto("pluto");

for(int i = 0; i < 3; ++i) { Dog other = pluto; }

Dog yetAnother = makeBarkAndReturn(pluto);

return 0;}

25 How to Shoot Yourself In the Foot

25.1 C++

You accidently create a dozen instances of yourself and shoot them all in the foot.

26 Ausgabe

creating dog plutocreating twin dog plutodestroying pluto :(creating twin dog plutodestroying pluto :(

13

Page 15: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

creating twin dog plutodestroying pluto :(creating twin dog plutopluto says wuffcreating twin dog plutodestroying pluto :(destroying pluto :(destroying pluto :(

27 const-Methoden

• Ändert eine Methode das Objekt nicht, so sollte man sie als const deklarieren.

// dog.hclass Dog{

/* ... */void talk() const;void meet(Dog &other);

}

• Klassen, bei denen alle Methoden const sind (ausser ctor und dtor) heissen immutable.• Prinzipiell ist es immer erstrebenswert, immutable Klassen zu verwenden.

28 Beispiel

// dog.hclass Dog { /*...*/

void talk() const;void meet(Dog &other);

}

int main() {Dog idefix("idefix");Dog snoopy("snoopy");idefix.meet(snoopy);const Dog & other = idefix;other.talk();// not possible: other.meet(snoopy)// not possible: snoopy.meet(other)return 0;

}

29 Dynamische Speicherverwaltung in C++

29.1 new

• new reserviert (wie malloc) Speicher.• new ruft ctor auf.

14

Page 16: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

29.2 delete

• delete gibt Speicher wieder frei• delete ruft dtor auf.

29.3 Arrays

• Mit new type[size] wird ein neues Array angelegt.• Arrays mit delete[] freigeben• In C++ Verwendung von Arrays selten.

29.4 Beispiel

Dog *pluto = new Dog("pluto");/* ... */delete pluto;

30 Zusammenfassung: MyArray, Array für int

// myarray.hclass MyArray {public:

MyArray(int len);MyArray(const MyArray& other);

~MyArray();

void set(int index, int value);int get(int index) const;int length() const;

private:int mLength; // cannot have same name as methodint * data;

}

31 MyArray: Konstruktor 1

MyArray::MyArray(int len) :mLength(len),data(new int[len]) {}

32 MyArray: Methoden

void MyArray::set(int index, int value) {data[index] = value;

}

15

Page 17: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

int MyArray::get(int index) const {// don't forget const!return data[index];

}

int MyArray::length() const {return mLength;

}

33 Destruktor

MyArray::~MyArray() {cout << "deleting data" << endl;delete[] data;

}

34 Copy-Constructor nötig?

34.1 Beispiel ohne expliziten Copy-Construktor

int main() {MyArray arr(1); // calls new in ctorarr.set(0, 3); // data[0] = 3

{MyArray arr2 = arr; // copy-ctor// the implicit copy-ctor executes// "arr2.data = arr.data"!

arr2.set(0, 1);// what is arr.get(0)?

} // calls dtor of arr2, deleting arr2.data

arr.set(0, 2); // wait, wasn't arr.data deleted?} // again, deleting data (double delete)

35 Copy-Constructor

MyArray::MyArray(const MyArray & arr) :length(arr.mLength), data(new int[mLength]) {// copy values of array to new arrayfor(int i = 0; i < mLength; ++i) {

// We easily can access data in "arr"// because, remember, private is// relative to the class, not the object!data[i] = arr.data[i];

}}

• Weitere implizite Funktionen sind problematisch (Rule of three)

16

Page 18: Einführung in objektorientiertes Programmieren in C++ · Einführung in objektorientiertes Programmieren in C++ Figure 1: Pluto 5 Allgemein Hunde •Eigenschaften: – Hunde haben

Einführung in objektorientiertes Programmieren in C++

– Destructor, Copy ctor, und– Copy assignment operator (normale Zuweisung [dazu in einer späteren Einheit])– In C++11 rule of 5 wegen “Move Semantic”: Move constructor, Move assignment

operator

36 So viel fürs Erste zu Objekten

• Zusammenfassend

– Klassen sind Beschreibungen, aus denen konkrete Dinge erstellt werden können

* Objekte sind Instanzen von Klassen– Objekte enthalten Membervariablen (Daten) und Methoden (Verhalten)– Objekte werden durch Aufruf eines Konstruktors erstellt und durch den Destruktor

zerstört– Objekte werden oft als Referenzen übergeben, um unnötiges Kopieren zu vermeiden

(sehr oft mit const-Modifier)

17