classes objects c
Eine kurze Einführung in Klassen und Objekte in C ++.
Klassen und Objekte sind die Bausteine der objektorientierten Programmierung in C ++. Jede lebende oder nicht lebende Entität kann als Objekt dargestellt und mit C ++ entsprechend programmiert werden. So können Entitäten wie ein Auto, ein Schreibtisch, eine Person, ein Vogel, ein Tier usw. als Objekte dargestellt werden.
Klasse ist eine Ebene höher als das Objekt und repräsentiert die Kategorie von Objekten. Somit fungiert die Klasse als Blaupause, die das Objektdesign und die Details beschreibt. Dies umfasst Daten, die zur Beschreibung des Objekts verwendet werden, sowie verschiedene Methoden oder Funktionen, die auf die Objektdaten einwirken können.
=> Sehen Sie sich hier die einfache C ++ - Schulungsserie an.
In diesem Tutorial werden alle Details von Klassen und Objekten in C ++ sowie deren programmatische Darstellung erläutert.
Was du lernen wirst:
- Klassen
- Objekte
- Zugriffsspezifizierer
- Konstruktoren
- Arten von Konstruktoren
- Aufgabenverwalter
- Zerstörer
- 'Dieser' Zeiger
- Fazit
- Literatur-Empfehlungen
Klassen
Eine Klasse in C ++ kann als Blaupause oder Skelett einer bestimmten Entität angesehen werden. Klasse ist ein benutzerdefinierter Datentyp. Es enthält die allgemeinen Informationen oder Daten für diese bestimmte Entität und die Funktionen, die für diese Entität ausgeführt werden.
In der C ++ - Syntax definieren wir eine Klasse mit dem Schlüsselwort 'class' gefolgt vom Namen der Klasse.
Dem Klassennamen folgen die Details der Klasse in geschweiften Klammern und werden durch ein Semikolon abgeschlossen.
Der folgende Block zeigt die allgemeine Syntax für die Klassendefinition.
Wie in der obigen Darstellung gezeigt, kann die Klasse über Zugriffsspezifizierer wie public / protected / private verfügen. Es kann Datenelemente und Elementfunktionen haben. Die Daten und Funktionen werden als Mitglieder der Klasse aufgerufen. Standardmäßig sind die Mitglieder für die Klasse privat, sodass keine externe Entität Zugriff auf diese Mitglieder hat.
Zum Beispiel, Ein Fahrzeug kann eine verallgemeinerte Klasse mit Eigenschaften wie Modell, Farbe, Fahrgestellnummer, Durchschnittsgeschwindigkeit usw. sein. Es kann Funktionen wie changeModel, Beschleunigen, Verlangsamen usw. haben, die Aktionen für die Datenelemente ausführen. Wir können eine Klasse mit dem Namen 'Fahrzeug' definieren, die alle diese Datenelemente und Funktionen enthält.
Wie bereits erwähnt, ist eine Klasse nur eine Blaupause für die Entitäten. Es nimmt keinen Speicherplatz in Anspruch, wenn es definiert ist. Damit eine Klasse funktionsfähig ist, müssen wir Objekte definieren, die die Mitglieder der Klasse verwenden können.
Objekte
Um die Klassenfunktionalität nutzen zu können, müssen wir die Klasse instanziieren, um ein Objekt zu erstellen. Ein Objekt ist eine Instanz einer Klasse. Mit einfachen Worten können wir sagen, dass ein Objekt eine Variable der Typklasse ist.
Die allgemeine Syntax zum Erstellen eines Objekts lautet:
classname object_name;
Sobald das Objekt erstellt wurde, kann es verwendet werden, um auf die Datenelemente und Funktionen dieser Klasse zuzugreifen.
Der Zugriff auf die Mitglieder der Klasse (Daten und Funktionen) erfolgt mit dem Punkt (.) -Operator, der auch als Mitgliederzugriffsoperator bezeichnet wird.
Wenn obj der Name des Objekts ist und die Klasse die Funktion „display ()“ enthält, kann auf die Funktion als „obj.display ()“ zugegriffen werden.
Die obige Aussage enthält jedoch einen Haken. Wir können mit einem Objekt und dem Punktoperator auf die Funktionsanzeige () zugreifen, wenn die Funktion 'öffentlich' ist.
Zugriffsspezifizierer
In C ++ hängt der Zugriff auf die Datenelemente und Funktionen in der Klasse vom Zugriff ab, der diesem bestimmten Datenelement oder dieser Funktion mithilfe eines Zugriffsspezifizierers gewährt wird.
C ++ unterstützt die folgenden Zugriffsspezifizierer:
# 1) Privat
Dies ist der Standardzugriffsspezifizierer für eine Klasse in C ++. Dies bedeutet, dass wenn für die Mitglieder einer Klasse kein Zugriffsspezifizierer angegeben ist, dieser als privat betrachtet wird.
Wenn ein Mitglied privat ist, kann außerhalb der Klasse nicht darauf zugegriffen werden. Nicht einmal das Objekt und den Punktoperator verwenden. Auf die privaten Datenelemente kann nur mit den Elementfunktionen der Klasse zugegriffen werden.
Befehlszeilenargumente in Shell-Skriptbeispielen
Es gibt jedoch eine Ausnahme von dieser Regel, die wir in unseren späteren Themen diskutieren werden.
# 2) Öffentlich
Ein Datenelement oder eine Funktion, die in der Klasse als öffentlich definiert ist, ist für alle außerhalb der Klasse zugänglich. Auf diese Elemente kann mit dem Objekt und dem Punktoperator zugegriffen werden.
# 3) Geschützt
Ein geschütztes Mitglied einer Klasse ist für die Klasse selbst und die untergeordneten Klassen dieser Klasse zugänglich.
Dieser Zugriffsspezifizierer wird insbesondere im Falle einer Vererbung verwendet, und wir werden dies im Detail diskutieren, während wir das Thema Vererbung diskutieren.
Nehmen wir das folgende Beispiel, um diese Zugriffsspezifizierer besser zu verstehen.
#include #include using namespace std; class ABC{ int var1 = 10; public: string name; void display() { cout<<'var1 ='< Ausgabe:
var1 = 10
Name = etw
In diesem Programm haben wir zwei Datenelemente, von denen var1 vom Typ int privat ist (Zugriffsspezifizierer nicht angegeben. Standard ist privat). Ein weiteres Mitglied ist der Stringname, der als öffentlich deklariert wird. Wir haben noch eine weitere Funktionsanzeige, die den Wert dieser beiden Elemente anzeigt.
In der Hauptfunktion deklarieren wir ein Objekt abc der Klasse ABC. Dann setzen wir Werte auf Datenelemente und auch die Anzeige der Aufruffunktion mit dem Objekt 'abc'.
Wenn der Compiler jedoch auf die Zeile abc.var1 = 20 stößt; Es wird ein Fehler generiert, dass 'var1 eine private Variable ist'.
Dies liegt daran, dass wir nicht auf private Datenelemente einer Klasse außerhalb der Klasse zugreifen können. Somit liegt ein Fehler vor. Wir können jedoch innerhalb der Funktion darauf zugreifen und daher den Wert von var1 in der Anzeigefunktion ausgeben. es wird kein Fehler ausgegeben.
Daher zeigt die Ausgabe des Programms den Anfangswert an, mit dem var1 deklariert wird.
Bisher haben wir die Details zu Klassen-, Objekt- und Zugriffsspezifizierern gesehen. Lassen Sie uns nun ein vollständiges Beispiel eines Beispielklassenschülers aufgreifen. Diese Klasse hat Datenelemente: student_id, student_name und student_age. Es hat auch Mitgliedsfunktionen zum Lesen von Schülerinformationen und zum Anzeigen von Schülerinformationen.
Um den Lesern die Arbeit zu erleichtern, haben wir alle Mitglieder der Klasse als öffentlich deklariert.
Das folgende Programm zeigt die vollständige Implementierung.
#include #include using namespace std; class student{ public: int student_id; string student_name; int student_age; void read_studentInfo(); void print_studentInfo() { cout<<'
Student ID : '<student_id; cout<>student_name; cout<>student_age; } int main() { student s1; s1.read_studentInfo(); s1.print_studentInfo(); }
Ausgabe:
Studenten-ID eingeben: 1
Geben Sie student_name ein: abc
Geben Sie student_age ein: 12
Studentenausweis: 1
Studentenname: abc
Studentenalter: 12
Somit haben wir eine vollständige Klasse, die oben definiert wurde. Der einzige bemerkenswerte Unterschied besteht darin, dass wir eine Funktion 'print_studentInfo' innerhalb der Klasse definiert haben, während die andere Funktion 'read_studentinfo' außerhalb der Klasse definiert ist. Auf diese zwei Arten können Elementfunktionen für eine Klasse definiert werden.
Beachten Sie, dass die außerhalb definierte Funktion noch eine Deklaration / einen Prototyp innerhalb der Klasse enthält. Es wird auch außerhalb der Klasse mit dem definiert Scope Resolution Operator (: :) . Dann erstellen wir in der Hauptfunktion ein Schülerklassenobjekt und rufen dann Funktionen zum Lesen und Anzeigen der Daten auf.
Konstruktoren
Bisher haben wir in diesem Lernprogramm ein einfaches Objekt erstellt und dann jedem Datenelement der Klasse in der Hauptfunktion Werte zugewiesen, nachdem wir diese Werte aus der Standardeingabe gelesen haben.
In diesem Thema werden wir uns eine spezielle Funktion ansehen, mit der das Objekt während seiner Erstellung initialisiert wird. Diese spezielle Funktion wird als Konstruktor bezeichnet.
Ein Konstruktor ist eine Elementfunktion der Klasse, unterscheidet sich jedoch in folgenden Punkten von der normalen Elementfunktion:
Wie kopiere ich ein Array in Java?
- Der Konstruktor hat keinen Rückgabewert, d. H. Der Konstruktor gibt niemals einen Wert zurück.
- Es ist eine öffentliche Mitgliedsfunktion der Klasse.
- Es wird verwendet, um die Datenelemente zu initialisieren und das Objekt der Klasse zu erstellen.
- Es wird vom Compiler automatisch aufgerufen, wenn das Objekt erstellt wird.
Arten von Konstruktoren
C ++ unterstützt die folgenden Konstruktortypen.
# 1) Standardkonstruktor
Ein Standardkonstruktor ist der Basiskonstruktor und hat keine Parameter. Mit dem Standardkonstruktor können wir ein einfaches Objekt ohne Parameter erstellen.
Der Standardkonstruktor hat die folgende Syntax:
classname() { //constructor code }
Wenn eine Klasse keinen Standardkonstruktor hat, erstellt der Compiler diesen.
# 2) Parametrisierter Konstruktor
Ein parametrisierter Konstruktor verfügt über eine Parameterliste, mit der wir die Klassenmitglieder initialisieren können. Wenn wir ein Objekt in einem parametrisierten Konstruktor deklarieren, müssen wir Anfangswerte als Parameter an die Konstruktorfunktion übergeben.
Eine parametrisierte Konstruktorfunktion sieht wie folgt aus.
classname(argument list){ //constructor code }
Ein parametrisierter Konstruktor wird verwendet, um Konstruktoren zu überladen. Wir werden in unseren späteren Themen mehr über Überlastung erfahren.
Ein parametrisierter Konstruktor wird zum Initialisieren von Datenelementen verschiedener Objekte verwendet. Dabei können wir verschiedene Werte von Datenelementen an verschiedene Objekte übergeben.
# 3) Konstruktoren kopieren
C ++ unterstützt einen dritten Konstruktortyp, den Kopierkonstruktor. Seine allgemeine Form ist
Klassenname (const Klassenname & obj);
Wie in der obigen Deklaration gezeigt, wird im Kopierkonstruktor ein neues Objekt mit den Werten eines anderen Objekts derselben Klasse erstellt. Der Parameter, der an den Konstruktor übergeben wird, ist die konstante Referenz eines Objekts, dessen Werte für die Erstellung des neuen Objekts verwendet werden.
Ein Kopierkonstruktor wird normalerweise in den folgenden Situationen aufgerufen:
- Wenn ein Klassenobjekt als Wert zurückgegeben wird.
- Wenn ein Objekt als Argument an eine Funktion übergeben und als Wert übergeben wird.
- Wenn ein Objekt aus einem anderen Objekt derselben Klasse erstellt wird.
- Wenn ein temporäres Objekt vom Compiler generiert wird.
Wir können jedoch nicht garantieren, dass der Kopierkonstruktor in allen oben genannten Fällen aufgerufen wird, da der C ++ - Compiler eine Möglichkeit hat, Kopiervorgänge zu optimieren.
Ein Kopierkonstruktor führt eine Mitgliederkopie zwischen Objekten durch. Genau wie der Standardkonstruktor erstellt der C ++ - Compiler einen Standardkopierkonstruktor, wenn wir keinen in unserem Programm bereitstellen. Wenn eine Klasse jedoch bestimmte Datenelemente wie Zeiger, Referenzen oder eine Laufzeitzuweisung von Ressourcen hat, benötigen wir einen eigenen benutzerdefinierten Kopierkonstruktor.
Der Grund ist, dass der Standardkopierkonstruktor nur eine flache Kopie von Datenelementen ausführt, d. H. Beide Objekte teilen sich denselben Speicherort. Dies ist in Ordnung für einfache Nicht-Zeiger-Datenelemente.
Wenn es jedoch um Zeiger oder andere dynamische Datenelemente geht, möchten wir, dass die Daten auf einen neuen Speicherort verweisen. Dies ist die Tiefenkopie und kann nur mit einem benutzerdefinierten Kopierkonstruktor erreicht werden.
Im Folgenden finden Sie ein vollständiges C ++ - Programm, das alle drei Arten von Konstruktoren und ihre Verwendung beim Erstellen eines Objekts implementiert.
#include #include using namespace std; class student{ public: int student_id; string student_name; int student_age; //default constructor student(){ student_id = 1; student_name = 'abc'; student_age = 10; } //parameterized constructor student(int id,string name,int age){ student_id = id; student_name = name; student_age = age; } //copy constructor student(const student& st){ student_id = st.student_id; student_name = st.student_name; student_age = st.student_age; } void print_studentInfo() { cout<<'
Student ID : '< Ausgabe:
********** s **********
Studentenausweis: 1
Studentenname: abc
Studentenalter: 10
********** s2 **********
Studentenausweis: 2
Studentenname: xyz
Studentenalter: 12
Der Screenshot dafür ist unten angegeben.
In diesem Programm haben wir einen Klassenschüler definiert, der dem im vorherigen Programm definierten ähnlich ist. Der Unterschied besteht darin, dass wir drei Konstruktoren definieren, anstatt Datenelementwerte aus der Standardeingabe über eine Funktion zu lesen.
Es ist absolut möglich, dass eine Klasse mehr als einen Konstruktor hat. Wir haben einen Standardkonstruktor, der die Datenelemente auf Anfangswerte initialisiert. Als nächstes definieren wir einen parametrisierten Konstruktor, der Anfangswerte als Parameter an den Konstruktor übergibt.
Als nächstes definieren wir einen Kopierkonstruktor, an den wir einen konstanten Verweis auf ein Objekt der Schülerklasse übergeben.
In der Hauptfunktion erstellen wir drei Objekte separat mit drei Konstruktoren. Das erste Objekt s wird mit dem Standardkonstruktor erstellt. Das zweite Objekt s1 wird mit dem parametrisierten Konstruktor erstellt, während das dritte Objekt s2 mit einem Kopierkonstruktor erstellt wird.
Beachten Sie die Erstellung des dritten Objekts s2. Hier ordnen wir das bereits erstellte Objekt s1 dem neuen Objekt s2 zu. Wenn wir also ein neues Objekt unter Verwendung des bereits vorhandenen Objekts erstellen, wird vom Compiler ein Kopierkonstruktor aufgerufen.
Aufgabenverwalter
Wir können die Werte eines Objekts auch einem anderen mit einem Zuweisungsoperator (=) zuweisen. In diesem Fall haben wir eine Anweisung wie s1 = s.
Der Unterschied zwischen dem Kopierkonstruktor und dem Zuweisungsoperator besteht darin, dass während der Kopierkonstruktor insgesamt ein neues Objekt erstellt, der Zuweisungsoperator nur die Werte eines Mitglieds des Objekts auf RHS denen des Objekts auf LHS zuweist. Dies bedeutet, dass die Objekte auf beiden Seiten eines Zuweisungsoperators vor der Zuweisung vorhanden sein müssen.
Zerstörer
Ein Destruktor ist ebenfalls eine spezielle Funktion wie ein Konstruktor, implementiert jedoch die Funktionalität, die dem Konstruktor genau entgegengesetzt ist. Während der Konstruktor zum Erstellen eines Objekts verwendet wird, wird ein Destruktor zum Zerstören oder Löschen eines Objekts verwendet.
Einige der Eigenschaften des Destruktors umfassen:
- Ein Destruktorname ist der gleiche wie der Klassenname, beginnt jedoch mit einem Tilde-Zeichen (~).
- Der Destruktor hat keinen Rückgabetyp.
- Ein Destruktor hat keine Argumente.
- Es kann nur einen Destruktor in einer Klasse geben.
- Der Compiler erstellt immer einen Standarddestruktor, wenn wir keinen für eine Klasse bereitstellen.
Die allgemeine Syntax eines Destruktors lautet:
~classname(){ //cleanup code }
Der Destruktor einer Klasse wird normalerweise in den folgenden Situationen aufgerufen:
- Wenn das Objekt den Gültigkeitsbereich verlässt, wird der Klassendestruktor automatisch aufgerufen.
- Ebenso wird der Destruktor aufgerufen, wenn das Programm die Ausführung beendet hat. Dies bedeutet, dass auch alle Objekte nicht mehr existieren. Daher wird der Destruktor jedes Objekts aufgerufen.
- Der Destruktor der Klasse wird auch aufgerufen, wenn der Operator 'Löschen' zum Löschen eines Objekts ausgeführt wird.
- Wir können den Destruktor auch explizit aufrufen, um alle Bereinigungsaktivitäten auszuführen, nachdem wir mit der Objektfunktionalität fertig sind.
Das folgende Beispiel zeigt die Arbeitsweise eines Destruktors.
#include using namespace std; class sample{ public: sample(){ cout<<'Constructor::sample called'< Ausgabe:
Konstruktor :: Beispiel aufgerufen
Dies ist eine Beispielklasse
Destructor :: ~ Beispiel aufgerufen
Der Screenshot für die obige Ausgabe ist unten angegeben.
Wir haben ein Klassenbeispiel definiert, in dem wir einen Konstruktor, einen Destruktor und eine Funktionsanzeige definiert haben. In der Hauptfunktion erstellen wir ein Objektobjekt des Klassenbeispiels und rufen dann die Anzeigefunktion für dieses Objekt auf.
Danach wird eine Rückgabe 0 ausgeführt. In der Ausgabe können wir sehen, dass in dem Moment, in dem die Anzeigefunktion zurückkehrt und die Programmsteuerung zur Anweisung return 0 kommt, der Destruktor ausgeführt wird. Dies bedeutet, dass es in dem Moment ausgeführt wird, in dem das Objekt den Bereich verlässt.
'Dieser' Zeiger
C ++ verwendet ein spezielles Konzept für die Objekte, das als 'dieser' Zeiger bezeichnet wird. Der Zeiger 'this' zeigt immer auf das aktuelle Objekt. Je nach Situation verwenden wir daher immer dann, wenn wir auf das aktuelle Objekt verweisen müssen, den Zeiger „this“.
Wir wissen, dass jedes Mal, wenn eine Instanz der Klasse, d. H. Ein Objekt, erstellt wird, eine separate Kopie der Datenelemente der Klasse für das Objekt erstellt wird. Wenn es jedoch um die Elementfunktionen der Klasse geht, teilen sich alle Objekte dieselbe Kopie.
Wenn also ein oder mehrere Objekte gleichzeitig auf die Elementfunktionen zugreifen, wie stellen wir dann sicher, dass die Elementfunktionen auf die richtigen Datenelemente zugreifen und diese ändern?
Dies ist der Ort, an dem „dieser“ Zeiger in Aktion tritt. Der Compiler übergibt einen impliziten Zeiger mit dem Funktionsnamen 'this'. Dies wird als 'dieser' Zeiger bezeichnet.
Der Zeiger 'this' wird als verstecktes Argument an alle Elementfunktionsaufrufe übergeben. Es ist normalerweise eine lokale Variable. Daher ist 'dieser' Zeiger ein konstanter Zeiger und sein Inhalt ist die Speicheradresse des aktuellen Objekts.
Beachten Sie, dass dieser Zeiger nur für nicht statische Elementfunktionen und nicht für statische Funktionen verfügbar ist. Dies liegt daran, dass auf die statischen Funktionen nicht über ein Objekt zugegriffen werden muss. Sie können direkt über den Klassennamen aufgerufen werden.
Normalerweise verwenden wir den Zeiger 'this' in Situationen, in denen die Elementvariablen und die Parameter übergeben werden, um die Elementvariablen mit demselben Namen zu initialisieren. Wir verwenden es auch, wenn wir das aktuelle Objekt von der Funktion zurückgeben müssen.
Lassen Sie uns die Demonstration dieses Zeigers unten sehen.
#include using namespace std; class Sample { private: int num; char ch; public: Sample &setParam(int num, char ch){ this->num =num; this->ch = ch; return *this; } void printValues(){ cout<<'num = '< Ausgabe:
num = 100
ch = A.
Im obigen Programm haben wir eine Klasse namens Sample mit zwei Datenelementen num und ch. Wir haben eine Mitgliedsfunktion setParam, die die Parameter mit denselben Namen, num und ch übergibt, um die Werte der Mitgliedsvariablen festzulegen.
Innerhalb der Funktion weisen wir diese Werte den aktuellen Objektelementvariablen zu, die durch diesen Zeiger angezeigt werden. Sobald die Werte eingestellt sind, wird das aktuelle Objekt 'this' von der Funktion zurückgegeben.
In der Hauptfunktion erstellen wir zuerst ein Objekt der Sample-Klasse obj und rufen eine setParam-Funktion auf, um die Werte festzulegen, und rufen dann die printValues-Funktion auf, um die Werte zu drucken.
Fazit
In diesem Tutorial haben wir die Grundbausteine von OOP in C ++ gelernt. Das Verständnis der Klassen und Objekte ist zunächst die Hauptanforderung an OOP in C ++. Wir haben auch anhand von Beispielen die Konstruktoren und Destruktoren im Detail kennengelernt.
In unserem nächsten Tutorial lernen wir die Initialisierungslisten in C ++ kennen.
=> Sehen Sie sich hier die einfache C ++ - Schulungsserie an.
Fragen und Antworten zu .net Framework-Interviews
Literatur-Empfehlungen
- Python-OOPs-Konzepte (Python-Klassen, Objekte und Vererbung)
- Java Interface und Abstract Class Tutorial mit Beispielen
- Arbeiten mit VBScript Excel-Objekten
- QTP-Tutorial Nr. 7 - QTP-Paradigma zur Objektidentifizierung - Wie identifiziert QTP Objekte eindeutig?
- Objekt-Repository in QTP - Tutorial Nr. 22
- Arbeiten mit VBScript ADODB-Verbindungsobjekten
- Laufzeitpolymorphismus In C ++
- Vererbung in C ++