C++-Programmierung/ Eigene Datentypen definieren/ Zusammenfassung
Deklaration und Definition
[Bearbeiten]Die Deklaration einer Klasse besteht nur aus ihrem Namen, welchem das Schlüsselwort class
vorangestellt wird. Die Definition einer Klasse beinhaltet die Deklaration aller Methoden und Variablen, welche Teil der Klasse sind; sie werden als Member (Mitglieder) der Klasse bezeichnet. Auch in diesem Fall gilt natürlich, eine Definition ist gleichzeitig eine Deklaration.
class «Klassenname»; // Deklaration
class «Klassenname»{ // Definition
// Klassenmember
};
Alle Methoden einer Klasse haben Zugriff auf sämtliche Member. Eine Klasse kann mehrere Konstruktoren und einen Destruktor enthalten, beides sind spezielle Methoden. Konstruktoren werden aufgerufen, wenn ein Objekt der Klasse erstellt wird. Der Destruktor wird aufgerufen, wenn ein Objekt der Klasse zerstört wird. Der Name der Konstruktoren ist immer gleich dem Klassennamen, beim Destruktor wird dem Klassennamen noch eine Tilde (~
) vorangestellt. Weder der Konstruktor noch der Destruktor haben einen Rückgabetyp. Konstruktoren besitzen außerdem eine sogenannte Initialisierungsliste, in welcher die Variablenmember eines Objekts initialisiert werden können. Im Funktionsrumpf eines Konstruktors sind keine Initialisierungen von Klassenmembern mehr möglich, hier lassen sich lediglich noch Zuweisungen vornehmen.
class «Klassenname»{
«Klassenname»() // Konstruktor (Definition)
:a(5) // Initialisierungsliste
{} // leerer Funktionsrumpf
«Klassenname»(int b) // weiterer Konstruktor (Definition)
:a(b) // Initialisierungsliste
{} // leerer Funktionsrumpf
~«Klassenname»(); // Destruktor (Deklaration)
«Rückgabetyp» «Methodenname»(); // eine Methode (Deklaration)
int a; // Membervariable
};
«Klassenname»::~«Klassenname»(){} // Definition des Destruktors
// Definition einer normalen Methode
«Rückgabetyp» «Klassenname»::«Methodenname»(){}
Zugriffsbereiche
[Bearbeiten]Innerhalb von Klassen gibt es verschiedene Zugriffsbereiche. Öffentliche Member (public
) können von überall aus aufgerufen und verändert werden. Private Member (private
) lassen sich nur von Methoden der Klasse aus ansprechen. Ein dritter Bereich (protected
) wird später noch vorgestellt werden. Der Standardbereich einer Klasse ist privat. Es kann mittels der Schlüsselwörter innerhalb der Klassendefinition beliebig oft zwischen den verschiedenen Bereichen gewechselt werden.
class «Klassenname»{
// Alles hier ist privat
public: // Ab hier ist alles öffentlich
private: // Ab hier ist alles privat
};
Freunde
[Bearbeiten]Manchmal ist es sinnvoll, auch einer Funktion außerhalb einer Klasse Zugriff auf deren private Member zu gewähren. Dafür muss diese innerhalb der Klassendefinition als friend
deklariert werden. Auch die Deklaration einer ganzen Klasse als friend
ist möglich, wenngleich selten sinnvoll. Freundschaft zwischen Klassen beruht im allgemeinen nicht auf Gegenseitigkeit. Die Deklaration eines Freundes ist nicht vom Zugriffsbereich abhängig.
class «Klassenname»{
friend «Funktionsdeklaration»;
friend «Klassendeklaration»;
};
Verwendung
[Bearbeiten]Objekte einer Klasse werden genau so erzeugt, wie dies bei Basisdatentypen der Fall ist. Falls ein Konstruktor nur einen Parameter hat, kann anstatt der runden Klammern, genau wie bei Basisdatentypen, auch das Gleichheitszeichen verwendet werden. Der Compiler ruft in jedem Fall einen Konstruktor auf, wenn ein Objekt erzeugt wird, und den Destruktor, wenn ein Objekt zerstört wird. Auf öffentliche Member können, durch einen Punkt vom Objekt getrennt (object.member
), zugegriffen werden. Für Zeiger auf Klassenobjekte kann die Dereferenzierung mit anschließendem Zugriff ((*objectzeiger).member
) mit dem dereferenzierenden Zugriffsoperator (objectzeiger->member
) ausgeführt werden.
Operatorüberladung
[Bearbeiten]In C++ können die meisten Operatoren für eigene Datentypen überladen werden. Dies kann als Member einer Klasse geschehen oder auch außerhalb. Falls die Überladung als Member erfolgt, so ist der erste Parameter ein Objekt der entsprechenden Klasse. Die Operatorfunktionen sehen genau so aus wie gewöhnliche Funktionen, ihr Name setzt sich aus dem Schlüsselwort operator
gefolgt von der jeweiligen Zeichenfolge des gewünschten Operators.
Eine Operatorüberladung ist immer dann sinnvoll, wenn dadurch die Lesbarkeit des Programms erhöht wird. Es muss also intuitiv erkennbar sein, was der Operator tut. In begründeten Ausnahmefällen kann es auch sinnvoll sein, einen Operator mit einer anderen Funktionalität auszustatten, als er dies bei den Basisdatentypen hat. Ein gutes Beispiel hierfür ist die Verwendung der Shiftoperatoren zur Ein- bzw. Ausgabe.
Die Cast-Operatoren sind eine spezielle Form der Operatorüberladung. Ähnlich einem Konstruktor, der ein Objekt einer anderen Klasse übernimmt, kann die Umwandlung auch durch einen Cast-Operator erfolgen. Der Name einer entsprechenden Funktion setzt sich aus dem Schlüsselwort operator
gefolgt vom gewünschten Datentyp zusammen. Eine Besonderheit dieser Funktionen ist, dass sie keinen Rückgabetyp angeben dürfen, denn dieser ist ja durch den Funktionsnamen bereits festgelegt.
Compilergenerierte Methoden
[Bearbeiten]Unter bestimmten Umständen wird der Compiler für Sie einen Standardkonstruktor, einen Kopierkonstruktor, einen Destruktor und eine Kopierzuweisung generieren. In vielen Fällen sind die compilergenerierte Methoden geeignet. Deklarieren Sie eine dieser Methoden selbst, wird Ihre Variante verwendet. Falls Sie eine der Methoden explizit nicht für Ihre Klasse wünschen, dann deklarieren Sie sie im privaten Bereich. Der Compiler wird dann einen Fehler erzeugen, wenn jemand versucht die Methode aufzurufen.