Wissensspeicher 10

Rekursion

  • Eine Funktion ruft sich selber auf, Beispiel: long fakultaet(int n);
  • Besteht aus
    • Rekursionsverankerung (→ Abbruchbedingung der Rekursion)
    • Rekursionsschritt (→ Mind. ein erneuter Aufruf der Funktion und Änderung der Parameter)
  • Je nach Problem ist die rekursive Variante einfacher umzusetzen
  • Die iterativer Variante kann schneller sein

pages/Kapitel08-page-01.svg

pages/Kapitel08-page-02.svg

pages/Kapitel08-page-03.svg

pages/Kapitel08-page-04.svg

pages/Kapitel08-page-05.svg

pages/Kapitel08-page-06.svg

pages/Kapitel08-page-07.svg

pages/Kapitel08-page-08.svg

pages/Kapitel08-page-09.svg

pages/Kapitel08-page-10.svg

pages/Kapitel08-page-11.svg

pages/Kapitel08-page-12.svg

pages/Kapitel08-page-13.svg

pages/Kapitel08-page-14.svg

pages/Kapitel08-page-15.svg

pages/Kapitel08-page-16.svg

pages/Kapitel08-page-17.svg

pages/Kapitel08-page-18.svg

pages/Kapitel08-page-19.svg

pages/Kapitel08-page-20.svg

Live-Demo - Sichtbarkeit

#include <iostream>

using namespace std;

struct Punkt {
    double m_x;
    double m_y;
};

int main() {
    Punkt p1{42, 21};
    p1.m_x = 42 * 3 / 10;
    cout << p1.m_x << endl;
}
compiler

pages/Kapitel08-page-21.svg

pages/Kapitel08-page-22.svg

pages/Kapitel08-page-23.svg

pages/Kapitel08-page-24.svg

pages/Kapitel08-page-25.svg

pages/Kapitel08-page-26.svg

pages/Kapitel08-page-27.svg

pages/Kapitel08-page-28.svg

pages/Kapitel08-page-29.svg

pages/Kapitel08-page-30.svg

pages/Kapitel08-page-31.svg

pages/Kapitel08-page-32.svg

pages/Kapitel08-page-33.svg

Live-Demo - Klassen

#include <iostream>
class punkt {
    // private: // Obsolet, da Standard in class
    double m_x;
    double m_y;

public:
    // Setter
    void setzeX(double x) {
        m_x = x;
    }
    void setzeY(double y) {
        m_y = y;
    }

    // Getter
    double gibX() const {
        return m_x;
    }
    double gibY() const {
        return m_y;
    }

    // Methodendefinition
    void verschiebe(double x_v, double y_v);

    bool gleich(punkt const& p) {
       p.gibX();  // Nur möglich, da gix() const ist.
        return p.m_x == m_x && p.m_y == m_y;
    }
};

// Funktionsimplementierung außerhalb von Klasse.
// Implementierung kann auch in einer anderen Datei geschehen.
void punkt::verschiebe(double x_v, double y_v) {
    m_y += y_v;
    m_x += x_v;
}

int main() {
    punkt p1, p2, p3;  // 3 Objekte
    p1.setzeX(5);
    std::cout << p1.gibX() << std::endl;
}
compiler

pages/Kapitel08-page-34.svg

pages/Kapitel08-page-35.svg

pages/Kapitel08-page-36.svg

pages/Kapitel08-page-37.svg

pages/Kapitel08-page-38.svg

pages/Kapitel08-page-39.svg

pages/Kapitel08-page-40.svg

pages/Kapitel08-page-41.svg

pages/Kapitel08-page-42.svg

pages/Kapitel08-page-43.svg

pages/Kapitel08-page-44.svg

pages/Kapitel08-page-45.svg

pages/Kapitel08-page-46.svg

pages/Kapitel08-page-47.svg

pages/Kapitel08-page-48.svg

pages/Kapitel08-page-49.svg

pages/Kapitel08-page-50.svg

pages/Kapitel08-page-51.svg

pages/Kapitel08-page-52.svg

pages/Kapitel08-page-53.svg

pages/Kapitel08-page-54.svg

pages/Kapitel08-page-55.svg

pages/Kapitel08-page-56.svg

pages/Kapitel08-page-57.svg

pages/Kapitel08-page-58.svg

pages/Kapitel08-page-59.svg

pages/Kapitel08-page-60.svg

pages/Kapitel08-page-61.svg

pages/Kapitel08-page-62.svg

pages/Kapitel08-page-63.svg

pages/Kapitel08-page-64.svg

pages/Kapitel08-page-65.svg

pages/Kapitel08-page-66.svg

pages/Kapitel08-page-67.svg

pages/Kapitel08-page-68.svg

pages/Kapitel08-page-69.svg

pages/Kapitel08-page-70.svg

pages/Kapitel08-page-71.svg

pages/Kapitel08-page-72.svg

pages/Kapitel08-page-73.svg

pages/Kapitel08-page-74.svg

pages/Kapitel08-page-75.svg

pages/Kapitel08-page-76.svg

pages/Kapitel08-page-77.svg

pages/Kapitel08-page-78.svg

pages/Kapitel08-page-79.svg

pages/Kapitel08-page-80.svg

pages/Kapitel08-page-81.svg

pages/Kapitel08-page-82.svg

pages/Kapitel08-page-83.svg

pages/Kapitel08-page-84.svg

pages/Kapitel08-page-85.svg

pages/Kapitel08-page-86.svg

pages/Kapitel08-page-87.svg

pages/Kapitel08-page-88.svg

pages/Kapitel08-page-89.svg

pages/Kapitel08-page-90.svg

pages/Kapitel08-page-91.svg

pages/Kapitel08-page-92.svg

pages/Kapitel08-page-93.svg

pages/Kapitel08-page-94.svg

pages/Kapitel08-page-95.svg

pages/Kapitel08-page-96.svg

pages/Kapitel08-page-97.svg

pages/Kapitel08-page-98.svg

pages/Kapitel08-page-99.svg

pages/Kapitel08-page-100.svg

pages/Kapitel08-page-101.svg

pages/Kapitel08-page-102.svg

pages/Kapitel08-page-103.svg

pages/Kapitel08-page-104.svg

pages/Kapitel08-page-105.svg

pages/Kapitel08-page-106.svg

pages/Kapitel08-page-107.svg

pages/Kapitel08-page-108.svg

pages/Kapitel08-page-109.svg

pages/Kapitel08-page-110.svg

pages/Kapitel08-page-111.svg

pages/Kapitel08-page-112.svg

pages/Kapitel08-page-113.svg

pages/Kapitel08-page-114.svg

pages/Kapitel08-page-115.svg

pages/Kapitel08-page-116.svg

pages/Kapitel08-page-117.svg

pages/Kapitel08-page-118.svg

pages/Kapitel08-page-119.svg

pages/Kapitel08-page-120.svg

pages/Kapitel08-page-121.svg

pages/Kapitel08-page-122.svg

pages/Kapitel08-page-123.svg

pages/Kapitel08-page-124.svg

pages/Kapitel08-page-125.svg

Live-Demo - Default-Parameter

#include <iostream>

using namespace std;

class Punkt {
private:
    double m_x;
    double m_y;
public:
    Punkt(double wx = 0.0, double wy = 0.0) : m_x(wx), m_y(wy) {

    }
    double getX(void) {
        return m_x;
    }
};

int main() {
    Punkt p1{};
    cout << p1.getX() << endl;

    Punkt p2{2.0};
    cout << p2.getX() << endl;

    Punkt p3{3.0, 4.0};
    cout << p3.getX() << endl;
}
compiler

Wissensspeicher 11

Objekt-orientierte Programmierung (aka Klassen)

  • Klassen sind fast wie zusammengesetzte Datentypen (struct)
  • Klassen
    • … fassen Daten (Attribute) und die dazugehörigen Operationen (Methoden) zusammen
    • … tellen den Bauplan dar
    • … bestimmen mittels private und public die Sichtbarkeit von Attributen und Methoden
    • Ohne explizite Angabe ist alles private
  • Objekte
    • … sind die Instanzen von Klassen
    • … können über den Punkt-Operator auf Attribute und Methden zugreifen
    • … belegen Speicherplatz
    • … muss zu Beginn seiner Lebenszeit konstruiert werden (→ Konstruktor)

Live-Demo - Recap Klassen 1

#include <iostream>

using namespace std;

class Punkt {
    double m_x;
    double m_y;
public:
    Punkt() { 
        m_x = 42.0;
        m_y = 21.0;
    }
    Punkt(double wx = 0.0, double wy = 0.0) : m_x(wx), m_y(wy) { }
    double getX(void) {
        return m_x;
    }
};

int main() {
    Punkt p1{};
    cout << p1.m_y << endl;
    cout << p1.getX() << endl;

    Punkt p2{2.0};
    cout << p2.getX() << endl;

    Punkt p3{3.0, 4.0};
    cout << p3.getX() << endl;
}
compiler

Live-Demo - Recap Klassen 2

#include <iostream>

using namespace std;

class Math {
    double m_pi = 3; // Pi ist glatt drei! :-)
    double m_boltzmann;
public:
    Math() = default;
    double getPi(void) {
        return m_pi;
    }
    double getBoltzmann(void) {
        return m_boltzmann;
    }
};

int main() {
    Math m;

    cout << m.getPi() << endl;
    cout << m.getBoltzmann() << endl;
}
compiler

pages/Kapitel08-page-126.svg

pages/Kapitel08-page-127.svg

pages/Kapitel08-page-128.svg

pages/Kapitel08-page-129.svg

pages/Kapitel08-page-130.svg

pages/Kapitel08-page-131.svg

pages/Kapitel08-page-132.svg

Live-Demo - Kopier-Konstruktor

#include <iostream>

using namespace std;

class Math {
    double m_pi;
public:
    Math(double _pi) : m_pi(_pi) {}
    Math(Math const & _m) : m_pi(_m.m_pi + 10) {
        cout << "Ich bin die Kopie!" << endl;
    }
    double getPi(void) {
        return m_pi;
    }
};

int main() {
    Math m(3.0);

    cout << m.getPi() << endl;

    Math k = m;
    cout << k.getPi() << endl;
}
compiler

pages/Kapitel08-page-133.svg

pages/Kapitel08-page-134.svg

pages/Kapitel08-page-135.svg

pages/Kapitel08-page-136.svg

pages/Kapitel08-page-137.svg

Live-Demo - Probleme beim Kopier-Konstruktor

#include <iostream>

using namespace std;

class KlassePtr {
public:
    int *m_a;
    KlassePtr(KlassePtr const &k) = default;
};

int main() {
    KlassePtr kp1{};
    kp1.m_a = new int[10];
    KlassePtr kp2 = kp1;

    cout << kp1.m_a << endl;
    cout << kp2.m_a << endl;    
}
compiler

pages/Kapitel08-page-138.svg

pages/Kapitel08-page-139.svg

pages/Kapitel08-page-140.svg

pages/Kapitel08-page-141.svg

pages/Kapitel08-page-142.svg

pages/Kapitel08-page-143.svg

pages/Kapitel08-page-144.svg

pages/Kapitel08-page-145.svg

pages/Kapitel08-page-146.svg

pages/Kapitel08-page-147.svg

pages/Kapitel08-page-148.svg

pages/Kapitel08-page-149.svg

pages/Kapitel08-page-150.svg

pages/Kapitel08-page-151.svg

pages/Kapitel08-page-152.svg

pages/Kapitel08-page-153.svg

pages/Kapitel08-page-154.svg

pages/Kapitel08-page-155.svg

pages/Kapitel08-page-156.svg

pages/Kapitel08-page-157.svg

pages/Kapitel08-page-158.svg

pages/Kapitel08-page-159.svg

Live-Demo - Destruktor

#include <iostream>

using namespace std;

class MeinFeld {
    int s;
    int *feld;
public:
    MeinFeld(): MeinFeld(10) {}
    MeinFeld(int n): s(n) {
        feld = new int[s];
        cout << "Habe 'feld' mit " << s << " elementen belegt: " << feld << endl;
    }
    int size() const { return s; }

    ~MeinFeld() {
        cout << "Gebe 'feld' frei: " << feld << endl;
        delete[] feld;
    }
};

int main() {
    MeinFeld a(42);

    return 0;
}
compiler

pages/Kapitel08-page-160.svg

pages/Kapitel08-page-161.svg

pages/Kapitel08-page-162.svg

pages/Kapitel08-page-163.svg

pages/Kapitel08-page-164.svg

pages/Kapitel08-page-165.svg

pages/Kapitel08-page-166.svg

pages/Kapitel08-page-167.svg

pages/Kapitel08-page-168.svg

pages/Kapitel08-page-169.svg

pages/Kapitel08-page-170.svg

pages/Kapitel08-page-171.svg

pages/Kapitel08-page-172.svg

pages/Kapitel08-page-173.svg

pages/Kapitel08-page-174.svg

pages/Kapitel08-page-175.svg

pages/Kapitel08-page-176.svg

pages/Kapitel08-page-177.svg

pages/Kapitel08-page-178.svg

pages/Kapitel08-page-179.svg

pages/Kapitel08-page-180.svg

pages/Kapitel08-page-181.svg

pages/Kapitel08-page-182.svg

pages/Kapitel08-page-183.svg

pages/Kapitel08-page-184.svg

pages/Kapitel08-page-185.svg

pages/Kapitel08-page-186.svg

pages/Kapitel08-page-187.svg

pages/Kapitel08-page-188.svg

pages/Kapitel08-page-189.svg

pages/Kapitel08-page-190.svg

pages/Kapitel08-page-191.svg

pages/Kapitel08-page-192.svg

pages/Kapitel08-page-193.svg

pages/Kapitel08-page-194.svg

pages/Kapitel08-page-195.svg

pages/Kapitel08-page-196.svg

pages/Kapitel08-page-197.svg

pages/Kapitel08-page-198.svg

pages/Kapitel08-page-199.svg

Live-Demo - Statische Klassen-Variablen

#include <iostream>

using namespace std;

class MyClass {
    int m_id;
    string m_name;
public:
    static int s_nextID;
    MyClass(): MyClass("empty") {}
    MyClass(string _s): m_id(s_nextID++), m_name(_s) {}
    int getID() const { return m_id; }
};

int MyClass::s_nextID = 42;

int main() {
    cout << MyClass::s_nextID << endl;

    MyClass k1{"NameA"};
    MyClass k2{"NameB"};
    MyClass k3{"NameC"};

    cout << k3.getID() << endl;

    return 0;
}
compiler

pages/Kapitel08-page-200.svg

pages/Kapitel08-page-201.svg

pages/Kapitel08-page-202.svg

pages/Kapitel08-page-203.svg

pages/Kapitel08-page-204.svg

pages/Kapitel08-page-205.svg

pages/Kapitel08-page-206.svg

pages/Kapitel08-page-207.svg

pages/Kapitel08-page-208.svg

Wissensspeicher 12

Konstruktoren und Destruktoren

  • … werden beim Erzeugen bzw. bei der Zerstörung der jeweiligen Objekte aufgrufen
  • Konstruktoren werden in der Reihenfolge gemäß der Deklaration aufgerufen
  • Desktruktoren in umgekehrter Reihenfolge
  • Konstruktoren werden zu Beginn ihrer Gültigkeit aufgerufen
    • vor Beginn des Programms (main())
    • an der Stelle der Deklaration
  • Destruktoren werden zum Ende ihrer Gültigkeit aufgerufen
    • am Ende eines Blocks aufgerufen
    • Ende des Programms aufgerufen

Statische Klassenvariablen

  • Statische Klassenvariablen gehören zu einer Klasse, nicht zu einem Objekt
  • Zugriff erfolgt mit :: anstatt .MyClass::next_ID

pages/Kapitel08-page-209.svg

pages/Kapitel08-page-210.svg

pages/Kapitel08-page-211.svg

pages/Kapitel08-page-212.svg

pages/Kapitel08-page-213.svg

pages/Kapitel08-page-214.svg

pages/Kapitel08-page-215.svg

pages/Kapitel08-page-216.svg

pages/Kapitel08-page-217.svg

pages/Kapitel08-page-218.svg

pages/Kapitel08-page-219.svg

Live-Demo - Klassen-Schablonen

#include <iostream>

using namespace std;

template<typename T>
class Punkt {
private:
    T m_x, m_y;
public:
    Punkt(): Punkt(0,0) {}
    Punkt(T _x, T _y): m_x(_x), m_y(_y) {}
    void setX(T _x) { m_x = _x; }
    void setY(T _y) { m_y = _y; }
    T getX(void) const { return m_x; }
    T getY(void) const { return m_y; }
};

int main() {
    Punkt<int> p1{3.0,4};
    cout << "(" << p1.getX() << "," << p1.getY() << ")" << endl;

    Punkt<double> p2{3.0,4.12};
    cout << "(" << p2.getX() << "," << p2.getY() << ")" << endl;
 
    Punkt<char> p3{'K','o'};
    cout << "(" << p3.getX() << "," << p3.getY() << ")" << endl;
    return 0;
}
compiler

pages/Kapitel08-page-220.svg

pages/Kapitel08-page-221.svg

pages/Kapitel08-page-222.svg

pages/Kapitel08-page-223.svg

pages/Kapitel08-page-224.svg

pages/Kapitel08-page-225.svg

pages/Kapitel08-page-226.svg

pages/Kapitel08-page-227.svg

pages/Kapitel08-page-228.svg

pages/Kapitel08-page-229.svg