Die Übersichtlichkeit der Seite wird durch Javascript erhöht. Ist dies aktiviert, werden die Texte unter den Überschriften durch Anklicken der Überschriften ein- und ausgeblendet.
Klassen sind beschreibungen von Objekten, die Eigenschaften und Funktionen enthalten. Alle Bestandteile einer Klasse sind vom Standard her privat, das bedeutet, sie können nur innerhalb der Klasse angesprochen werden. Um die Klasse nutzen zu können benörigt man auch immer einen öffentlich ansprechbaren Bereich. Dieser wird mit dem Schlüsselwort public definiert, so dass alles, was folgt öffentlich nutzbar ist. Möchte man in der Folge wieder Private Bestandteile definieren nutzt man das Schlüsselwort private.
class Klassenname{ public: Typ elementfunktion1(); Typ elementfunktion2(); private: Typ attribut1; Typ attribut2; Typ interneFunktion(); };
class Klassenname{ ... };
Ein Konstruktor ist eine besondere Klassenfunktion, die Speicherplatz für ein erzeugtes Objekt bereitstellt. Dabei wird der Kondstruktor automatisch vom System bereitgestellt. Sollen allerdings definierte Zustände übergeben werden, so ist dieser Konstruktor zu überschreiben:
class Klassenname{ public: Klassenname(){ attribut1=0; attribut2=1; } private: Typ attribut1; Typ attribut2; };
Wird dann ein Objekt der Klasse deffiniert, werden die Atribute der Klassen wie definiert belegt:
Klassenname Objekt1;
Die Attribute können auch ohne einen selbst geschriebenen Standard-Konstruktor mit Standardwerten versehen werden, indem die Werte direkt bei der Deklaration übergeben werden:
class Klassenname{ public: ... private: attribut1 = 0; attribut2 {0}; };
Allgemeine Konstruktoren ermöglichen es im Gegensatz zu Standardkonstruktoren Argumente entgegenzunehmen und können wie Funktionen auch überladen werden. Auch ein Allgemeiner Konstruktor verhindert die Erzeugung eines Standardkonstrukters durch das System.
class Klassenname{ public: Klassenname(Typ Argument1, Typ Argument2){ attribut1 = Argument1; attribut2 = Argument2; } private: Typ attribut1; Typ attribut2; };
Objekte können dann wie folgt deffiniert werden:
Klassenname objekt1(70,90); Klassenname objekt2 = {50,51}; Klassenname objekt3 {25,50};
Wenn es mehrere Allgemeine Konstruktoren gibt wird der richtige anhand der Anzahl und Datentypen aufgerufen.
class Klassenname{ public: Klassenname( Typ argument1, Typ argument2 = 100){ attribut1 = argument1; attribut2 = argument2; } private: Typ attribut1; Typ attribut2; };
Konstruktor Initialisierungsliste
Dies bringt Laufzeitvorteile:
class Klassenname{ public: Klassenname(Typ Parameter1, Typ Parameter2) : attribut1 {Parameter1}, attribut2 {Parameter2} { // ggf Anweisungen oder leerer Block } private: Typ attribut1; Typ attribut2; };
Mit Hilfe von initializer_list ist es möglich eine Liste mit beliebig vielen Werten entgegenzunehmen. Beispiel:
#include<initializer_list> #include<vector> class Zahlenfolge{ public: Zahlenfolge(std::initializer_list<int> liste){ folge.assign(liste); } private: std::vector<int> folge; };
Die Zuweisung einer Zahlenfolge erfolgt dann immer in geschweiften Klammern:
Zahlenfolge z1{1,2,3,4,5,6,7,8,9};
Hat man einen weitern Konstruktor, der ein oder zwei Parameter entgegen nimmt, so wird dieser in dem Fall nur aufgerufen, wenn die Parameter in runden Klammern übergeben werden.
Der Kopierkonstruktor dient dazu, ein Objekt mit einem anderen zu initialisieren. Er entspricht einem Algemeinen Konstruktor, dem eine Referenz auf ein Objekt der selben Klasse übergeben wird.
class Klassenname{ public: Klassenname(const Klassenname& Objekt) : attribut1{Objekt.attribut1}, attribut2{Objekt.attribut2} { } private; Typ attribut1; Typ attriput2; };
Der hier gezeigte Kopierkonstruktor entspricht dem vom System automatisch erzeugten. Mit dem Kopierkunstruktor kann dann ein Objekt wie folgt erzeugt werden:
Klassenname Objekt1(19,39); Klassenname ObjektKopie1 = Objekt1 Klassenname ObjektKopie2(Objekt1);
Der Typumwandlungskonstruktor dient zum Umwandeln anderer Datentypen in die gewünschte Klasse. Dabei wird als Argument ein Objekt einer anderen Klasse üergeben.
class Klassenname{ public: [explicit] Klassenname(const Typ& Objekt) { // Prozedur, die die Attribute aus dem // übergebenen Objekt ermittelt und // entsprechend setzt } private: Typ attribut1; Typ attribut2; };
Wird das Schlüsselwort explicit vorangestellt, wird eine automatische Typumwandlung des Compilers verhindert. Für diesen Fall müsste der Aufruf der Typumwandlung expliziet angeforedert werden:
string wo("20,400"); Ort dort = Ort(wo);
Lässt mann dies weg, so ist die Typprüfung eingeschränkt, folgende Zuweisung ist dann möglich und führt in diesem Fall zu einem korrekten Ergebnis:
string wo("20,400"); Ort dort = wo;
Konstruktorsteuerung / default, delete
Mit default kann die Nutzung des Compiler-generierten Konstruktors ermöglicht werden, auch wenn es schon einen allgemeinen Konstruktor gibt.
class Klassenname { public: Klassenname() = default; Klassenname(int i=0) : attribut1{i} {} private: int attribut1; };
Mit delete ist es möglich die automatische Erzeugung eines Konstruktors durch den Compiler zu verbieten.
class Klassenname { public: Klassenname(const Klassenname&) = delete; //Kopieren verbieten private: Typ Attribut1; };
Der Sinn besteht darin, die Initialisierung von Attributen ohne Code-Duplikation zu erreichen.
class Klassenname{ public: Klassename(Typ parameter1, Typ parameter2) : Attribut1{parameter1}, Attribut2{Parameter2} {} // Konstruktor1 Klassenname() : Klassenname(1,42){} // Delegation an Konstruktor 1 private: Typ Attribut1; Typ Attribut2; };
constexpr-Konstruktor und Methoden
Mit constexpr wird die Berechnung sofern möglich zu Compilationszeit bereits angestoßen. Dies schafft Laufzeitvorteile. Ein constexpr-Objekt ist immer auch const. Seine Erzeugung setzt voraus:
Am Beispiel eines Kreises:
#include <iostream> #include <pi.h> class Kreis{ public: constexpr Kreis(double r) : radius{r}{ if (radius<0){ std::cerr << "Fehler: negativer Radius" << std::endl; exit(1); } } constexpr double getRadius() const { return radius } constexpr double getFlaeche() const { return radius * radius * pi<double>; } constexpr void setRadius(double r){ radius=r; } private: double radius; }; template<typename T> constexpr T pi = 3.14159265358979323846264338328L;
Die Klasse kann dann wie folgt verwendet werden:
constexpr Kreis ck(100.0); constexpr double cr = ck.getRadius(); constexpr double cf = ck.getFlaeche();
Destruktoren werden bei der Löschung eines Objektes aufgerufen. Sie werden automatisch durch den Compiler erzeugt, können aber überschrieben werden. Durch Destruktoren sollen die Ressourcen für ein Objekt wieder freigegeben werden. Die Reihenfolge des Aufrufes der Destruktoren ist umgekehrt wie die der Konstruktoren. (Last in First out) Destruktoren haben keine Argumente und Rückgabetypen
class Klassenname{ public: ~Klassenname(){ // Code der bei der Zerstörung des Objektes ausgeführt werden soll } };