Klassen und Objekte
Grundlegender Aufbau einer Klasse
Eine Klasse wird mit Hilfe des Schlüsselwortes class deklariert. Die Elemente einer Klasse werden in Attribute und Methoden unterteilt. Diese wiederum können unterschiedliche Zugriffsrechte haben - private, public, protected.
Eine Klasse muss deklariert und implementiert werden. Aus diesem Grund befinden sich Klassendeklarationen in der Regel in einer eigenen Header-Datei. Der Name der Datei ist dabei gleich dem Klassennamen. Heißt die Klasse also Person, wird diese in der Datei person.h gespeichert.
Die Implementierung steht dabei in einer .cpp Datei. In diesem Fall also person.cpp. Um die Deklaration der Klasse aus der .h (Header) Datei verwenden zu können, muss die Header-Datei in der .cpp Datei implementiert werden. Das geschieht durch #include "headerdatei.h"
Statt dem Schlüsselwort class kann auch struct verwendet werden. Werden die Marken private und public weggelassen, so ist die Voreinstellung bei class = private und die Voreinstellung bei struct = public.
class Klasse {
private:
// Private Daten und Funktionen,
// die nur in dieser Klasse bekannt sind.
public:
// Öffentliche Daten und Funktionen,
// die auch außerhalb dieser Klasse bekannt sind.
protected:
// Geschützte Daten und Funktionen,
// die innerhalb der Klasse und den Erben bekannt sin.
};
Mehr C++ Code Beispiele zur objektorientierten Programmierung findest du bei Codevisionz:
Beispiel
Im folgenden Beispiel wird eine Klasse spieler erstellt, die 3 Attribute besitzt (leben, energie und level) und eine Methode, welche die Attribute auf der Konsole ausgeben soll.
Hierbei ist anzumerken, dass Attribute normalerweise in den private Bereich gehören und somit dieses Beispiel nur als Einstiegshilfe dienen soll. In den folgenden Beiträgen wird auf die Anwendung von Konstruktoren, Destruktoren, getter/setter eingegangen, und gezeigt wie ein Programm mit deren Hilfe besser geschrieben wird.
class spieler {
public:
int leben;
int energie;
int level;
void spieler_info ();
};
#include <iostream>
#include "spieler.h"
using namespace std;
void spieler::spieler_info () {
cout << "Leben: " << leben << endl;
cout << "Energie: " << energie << endl;
cout << "Level: " << level << endl;
}
#include "spieler.h"
void main () {
spieler s;
s.leben = 100;
s.energie = 100;
s.level = 1;
s.spieler_info();
}
Konstruktoren
Konstruktoren sind ein wesentlicher Bestandteil von Klassen. Ein Konstruktor ist eine spezielle Methode einer Klasse und dient der Initialisierung von Eigenschaften. Bei der Erzeugung eines Objektes wird der Konstruktor automatisch also implizit aufgerufen, er kann also nicht wie andere Methoden explizit aufgerufen werden.
Ein Konstruktor weißt einige Besonderheiten auf. Zum einen ist der Name des Konstruktors identisch mit dem Namen der Klasse. Außerdem hat er keinen Rückgabewert. Da ein Konstruktor eine Methode ist kann er überladen werden und Defaultwerte für Parameter enthalten.
Ist kein passender Konstruktor vorhanden, wird das Objekt nicht erzeugt und der Compiler gibt eine Fehlermeldung aus.
Destruktoren
Destruktoren werden als Methode deklariert, um Aktionen festzulegen, wenn ein Objekt zerstört wird. Meistens wird Speicherplatz wieder freigegeben. Der Destruktor weist einige Besonderheiten auf:
Der Name ist gleich mit dem Klassennamen, jedoch mit vorangestellten Tilde (~) und
Der Destruktor kann nicht überladen werden, hat keine Argumente und keinen Rückgabetyp.
#ifndef _UHRZEIT_H
#define _UHRZEIT_H
class Uhrzeit {
private:
int stunde, sekunde;
public:
Uhrzeit(int stunde=0, int sekunde=0); // Konstruktor
void printUhrzeit();
};
#endif
#include <iostream>
#include "uhrzeit.h"
using namespace std;
Uhrzeit::Uhrzeit(int std, int sek) {
this->stunde = std;
this->sekunde = sek;
}
void Uhrzeit::printUhrzeit() {
cout << "Uhrzeit: " << stunde << ":" << sekunde << endl;
}
#include "uhrzeit.h"
int main() {
Uhrzeit u1(17,20); // Verwendung des Konstruktors -> Klassenname Objektname(Initialisierungsliste)
u1.printUhrzeit();
}
get-/set-Methoden (getter, setter)
Die set-Methodensetzen Eigenschaften und sind in den meisten Fällen vom Typ void, da sie keinen Rückgabewert haben.
Die get-Methoden weisen allerdings einen bestimmten Datentyp als Rückgabewert auf. Außerdem kommt ein const hinter die get-Methoden, da diese nur zur Rückgabe von Werten gedacht sind:
Warum benötigt man diese beiden Funktionen überhaupt? Es geht ja offensichtlich auch ohne, wie im Beispielprogram Spieler. In diesem Beispiel müssen die Attribute allerdings öffentlich sein, damit sie im main Programmteil direkt manipuliert werden können.
Genau dies ist aber nicht Sinn und Zweck der objektorientierten Programmierung. Deshalb werden die Attribute zwecks Datenkapselung in den private-Bereich gepackt.
Dadurch wird man allerdings gezwungen den "Umweg" über Methoden zu machen. Allerdings wird durch diesen Umweg gewährleistet, dass dem Attribut nur die vorgegebenen Werte zugeordnet werden können.
#ifndef _RECHTECK_H
#define _RECHTECK_H
class Rechteck {
private:
int laenge, breite;
public:
Rechteck(int laenge=0, int breite=0);
void setlaenge(int);
void setbreite(int);
int getlaenge() const;
int getbreite() const;
int getumfang() const;
void print();
};
#endif
#include "rechteck.h"
#include <iostream>
Rechteck::Rechteck(int a, int b) {
this->laenge = a;
this->breite = b;
}
void Rechteck::setlaenge(int a) {
this->laenge = a;
}
void Rechteck::setbreite(int b) {
this->breite = b;
}
int Rechteck::getlaenge() const {
return this->laenge;
}
int Rechteck::getbreite() const {
return this->breite;
}
int Rechteck::getflaeche() const {
return this->laenge * this->breite;
}
void Rechteck::print() {
std::cout << "Das Rechteck hat die Laenge: " << laenge << " und die Breite: " << breite << std::endl;
std::cout << "Flaeche: " << getflaeche() << std::endl;
}
#include "rechteck.h"
#include <iostream>
using namespace std;
void main() {
Rechteck r1(5,6);
Rechteck r2(10,10);
r1.print();
r2.print();
}
keyboard_arrow_left | Vorheriger ArtikelEinrichtung / InstallationEntwicklungsumgebung und Compiler |
Nächster ArtikelVererbungGrundlagen, Zugriffskontrolle, Beispiele |