private/public)Im letzten Kapitel ausgeklammert:
Wie werden Objekte, die Member sind, korrekt initialisiert?
(Die Destruktoren von Membern werden übrigens auch automatisch bei Aufruf des Destruktors aufgerufen)
#include <iostream>
using std::cout, std::endl;
class Foo {
int i;
public:
Foo() : i(0) { cout << "Foo default constructor called" << endl; }
Foo(int num) : i(num) { cout << "Foo constructor called" << endl; }
~Foo() { cout << "Foo destructor called" << endl; }
int value() { return i; }
};
class Bar {
Foo f;
double j;
public:
Bar(double d) : j(d) { cout << "Bar default constructor called" << endl; }
Bar(int num, double d) : f(num), j(d) { cout << "Bar constructor called" << endl; }
~Bar() { cout << "Bar destructor called" << endl; }
void print() { cout << "Values: " << f.value() << ", " << j << endl; }
};
int main() {
cout << "Entering main()" << std::endl;
Bar b(1, 2.5);
b.print();
cout << "Exiting main()" << std::endl;
}
Und nun zur Vererbung 🥳
Bessere Lösung: Vererbung
Tiere haben gemeinsame Eigenschaften
AnimalUnterklassen Dog und Cat erben von Animal
Wichtige Eigenschaft: Jede Instanz einer Unterklasse ist gleichzeitig Instanz der Oberklasse
Randbemerkung: Der Vorgang des Erbens wird häufig auch Ableitung genannt
→ „Dog wird von Animal abgeleitet“
Auch hier gilt: Die Begriffe Erben und Ableiten werden häufig synonym verwendet
Ist jetzt alles geklärt? Leider nein 🙁
private bedeutet wirklich privat!
→ nur die Klasse kann zugreifen
Die Methode bellen() erzeugt Compiler-Fehler
#include <string>
#include <iostream>
using std::cout;
using std::string;
class Animal {
private:
string name;
string laut;
public:
Animal() = delete;
Animal(string n, string l):
name(n), laut(l) {}
};
class Dog : public Animal {
private:
bool lieb = true;
public:
Dog(string name, string laut):
Animal(name, laut) {}
void bellen() { cout << this->laut; }
};
int main() {
Dog paul("Paul", "Wuff");
paul.bellen();
}
protected 🔒
private und publicprotected sind für Kindklassen sichtbarDer Bereich protected ist so etwas wie ein Familiengeheimnis
→ Die Kinder kennen es, aber außerhalb der Familie niemand
private entspricht hingegen einem persönlichen Geheimnis
→ Ist nur der Klasse selbst bekannt
Jetzt funktioniert alles ✅
#include <iostream>
using namespace std;
class Animal {
private: // Unsichtbar in Kind
bool secret = true;
protected: // Ab hier: sichtbar
std::string name;
std::string laut;
public:
Animal() = delete;
Animal(string n, string l):
name(n), laut(l) {}
};
class Dog : public Animal {
public:
Dog(string name, string laut):
Animal(name, laut) {}
void bellen() { cout << this->laut << endl; }
};
int main() {
Dog paul("Paul", "Wuff Wuff");
paul.bellen();
}
private deklariert
privateprotected (verbietet public)publicPoodle sind die Klassen Mother und Father noch gar nicht deklariert#include <string>
#include <iostream>
using std::string;
using std::cout;
class Animal {
protected: // Ab hier: sichtbar
std::string name;
std::string laut;
public:
Animal() = delete;
Animal(string n, string l):
name(n), laut(l) {}
};
class Dog : public Animal {
public:
Dog(string name, string laut):
Animal(name, laut) {}
void bellen() { cout << this->laut; }
};
class Father;
class Mother;
class Poodle: public Dog {
protected:
bool flauschig = true;
Father* vater;
Mother* mutter;
public:
Poodle(string name, string laut) :
Dog(name, laut), vater(nullptr), mutter(nullptr) {}
Poodle(string name, string laut, Father* v, Mother* m) :
Dog(name, laut), vater(v), mutter(m) {}
};
class Father: public Poodle {
bool is_father = true;
public:
Father(string name, string laut) :
Poodle(name, laut) {}
};
class Mother: public Poodle {
bool is_mother = true;
public:
Mother(string name, string laut) :
Poodle(name, laut) {}
};
int main() {
Father paul_senior ("Paul Senior", "Wau");
Mother martha ("Martha", "Woof");
Poodle paul("Paul", "Wuff Wuff", &paul_senior, &martha);
paul.bellen();
}
Animal → Array vom Typ Animalvirtual hilft hierbei → mehr im nächsten Kapitelpublic → für alle zugreifbarprotected → nur für die Klasse und Unterklassenprivate → nur für die Klasse selbst