Elementares C++ – Klassen und Objekte (1)

Einführung von Klassen

In der Sprache C würden wir einen Stapel wie folgt schreiben:

struct Stack
{
    
    
	int* a;
	int top;
	int capacity;
};

void StackInit(struct Stack* ps);
void StackPush(struct Stack* ps, int x);

Schreiben Sie zuerst eine Stapelstruktur und dann die mit dem Stapel verbundenen Funktionen. Wir werden den Operationsteil des Stapels aufteilen, sodass wir sagen, dass die C-Sprache prozessorientiert ist.

Und inC++ können für Strukturen auch Funktionen in die Struktur geschrieben werden;< a i=3> und für Bei Strukturvariablentypen kann struct weggelassen werden

#include<stdlib.h>
struct Stack
{
    
    
	int* a;
	int top;
	int capacity;

	void Init()
	{
    
    
		a = (int*)malloc(sizeof(int)*4);
		top = 0;
		capacity = 4;
	}
	void Push(int x)
	{
    
    
		//空则扩容
		if (top == capacity)
		{
    
    
			int newcapacity =  capacity * 2;

			int* New = (int*)realloc(a, sizeof(int) * (newcapacity));
			if (New == nullptr)
			{
    
    
				perror("Newsapce Fail");
				exit(-1);
			}
			a = New;
			capacity = newcapacity;
		}
		//插入
		a[top] = x;
		top++;
	}
};

int main()
{
    
    
	Stack s1;
	s1.Init();
	s1.Push(5);
	
}

Die Definition der obigen Struktur,C++ bevorzugt stattdessen die Verwendung von Klasse

Klassendefinition

class Student
{
    
    

};

class ist das Schlüsselwort, das eine Klasse definiert, Student ist der Name der Klasse und der Hauptteil der Klasse steht in Klammern; im Allgemeinen ähnelt es struct;
Im Hauptteil, der Klassenkörper Inhaltwird aufgerufenMitglieder der Klasse: Variablen in einer Klasse werden Attribute der Klasse oder Mitgliedsvariablen genannt < a i=4>; Funktionen in einer Klasse werden Methoden der Klasse oder genanntMitgliedsfunktion

class Stack
{
    
    
private:
	int* a;
	int top;
	int capacity;
public:
	void Init()
	{
    
    
		a = nullptr;
		top = 0;
		capacity = 4;
	}
	void Push(int x)
	{
    
    
		//空则扩容
		//...
		//插入
		a[top] = x;
		top++;
	}
};

privat und öffentlich sindZugriffsqualifizierer.

Es gibt im Allgemeinen zwei Möglichkeiten, Klassendefinitionen zu schreiben. Die erste besteht darin, den Inhalt der Mitgliedsfunktion wie oben direkt in die Klasse zu schreiben. Die andere besteht darin, die Mitgliedsfunktionsdeklaration in der Klasse zu platzieren und die Funktionsdefinition in eine andere Datei zu schreiben.
Fügen Sie hier eine Bildbeschreibung ein

Hinweis: Bei der ersten Methode wird durch die Definition der Funktion direkt in der Klasse der Funktionsinhalt direkt in der Klasse erweitert. Mit anderen Worten, wenn sie direkt in der Klasse definiert wird, entspricht sie einer Inline-Funktion, also wenn der Funktionsinhalt lang ist, wird dennoch empfohlen, die zweite Methode zu schreiben.

Zugriffsqualifizierer

Fügen Sie hier eine Bildbeschreibung ein
C++ verwendet Zugriffsqualifizierer, um Zugriffsrechte zwischen verschiedenen Codeblöcken zu steuern. Sie bestimmen, ob auf Mitglieder einer Klasse zugegriffen und diese verwendet werden können.

öffentlich: Auf von der Öffentlichkeit geänderte Mitglieder kann von jedem Codeblock aus zugegriffen werden.

protected: Auf durch protected geänderte Mitglieder kann von der aktuellen Klasse, derselben Paketklasse usw. zugegriffen werden.
private: Auf von pricate geänderte Mitglieder können nur andere Mitglieder innerhalb der aktuellen Klasse zugreifen.

ZugriffsberechtigungsbereichBeginnen Sie dort, wo dieses Zugriffsqualifikationsmerkmal auftritt, bis das nächste Zugriffsqualifikationsmerkmal erscheint

Zugriffsqualifizierer sind nur zur Kompilierungszeit nützlich. Wenn die Daten dem Speicher zugeordnet werden, gibt es keinen Unterschied bei den Zugriffsqualifizierern.

Dies kann auch den Unterschied zwischen Klasse und Struktur erklären:
C++ muss mit der Sprache C kompatibel sein, damit Struktur in C++ als Struktur verwendet werden kann. Darüber hinaus kann struct in C++ auch zum Definieren von Klassen verwendet werden. Es ist dasselbe wie die Definition einer Klasse durch eine Klasse. Der Unterschied besteht darin, dass die Standardzugriffsberechtigung einer durch die Struktur definierten Klasse öffentlich ist und die Standardzugriffsberechtigung einer durch die Klasse definierten Klasse privat ist. Wir werden also in der Klasse class eindeutig privat und öffentlich schreiben.

Hinweise zu den Kursteilnehmern

Konflikt mit Variablennamen

class Date
{
    
    
private:
	//声明
	int _year;
	int _month;
	int _day;
public:
	void Init(int year, int month, int day)
	{
    
    
		/*year = year;
		month = month;
		day = day;*/
		//错误的,变量名冲突

		_year = year;
		_month = month;
		_day = day;
	}

	void Print()
	{
    
    
		cout << _year << "-" << _month << "-" << _day << endl;
	}
	
};

Beim Definieren von Mitgliedsvariablennamen müssen Sie darauf achten, ob die Namen von Mitgliedsvariablen in Konflikt geraten, da sie sich alle im selben Bereich befinden. Daher wird empfohlen, dem Namen der Mitgliedsvariablen ein zusätzliches Symbol hinzuzufügen, um anzuzeigen, dass es sich um eine Mitgliedsvariable handelt um die Variablen zu unterscheiden. Name.

Instanziierung der Klasse

Klasse stimmtObjektWas beschrieben wird, ist so etwas wie ein Modell, das die Mitglieder einer Klasse begrenzt. Durch das Definieren einer Klasse wird kein tatsächlicher Speicherplatz für deren Speicherung zugewiesen.

int main()
{
    
    
	Date d1;
	Date d2;
	//....
}

Wir rufen die oben genannten d1- und d2-Objekte der Klasse auf.
Eine Klasse kann mehrere Objekte instanziieren und die instanziierten Objekte belegen den tatsächlichen physischen Raum.Member-Variablen der Speicherklasse

Deklaration und Definition von Klassenmitgliedern

struct Stack
{
    
    
	int* a;
	int top;
	int capacity;
};
int main()
{
    
    
	Stack s1;
	s1.capacity = 10;
	//正确的
	Date d1;
	d1._year=10;
	//错误的
}

Wie im obigen Qualifikationsmerkmal erwähnt, sind die Mitgliedsvariablen von Date alle privat und können außerhalb des Bereichs nicht aufgerufen werden. Der Stapel wird durch die Struktur definiert, sodass wir darauf zugreifen dürfen. Hier ist jedoch zu beachten, dass die Mitgliedsvariablen in Date eigentlich nur Deklarationen sind und die tatsächlichen Definitionen definiert werden, wenn das Objekt erstellt wird.

Wir können so testen:
Fügen Sie hier eine Bildbeschreibung ein
Schreiben Sie eine Mitgliedsvariable in den öffentlichen Qualifizierer.
Fügen Sie hier eine Bildbeschreibung ein
Sie kann außerhalb des Gültigkeitsbereichs verwendet werden, da sie öffentlich ist ;

Wenn wir mehrere Objekte definieren,
Fügen Sie hier eine Bildbeschreibung ein
können diese auch den entsprechenden Inhalt ausdrucken.
Dies zeigt, dass für die Mitgliedsvariablen der Klasse sie einfach in der Klasse deklariert werden, unabhängig davon, ob sie privat oder öffentlich sind, sie sind nur Qualifizierer. Definitionen müssen in Objekten erfolgen, damit der Zugriff in mehreren Objekten nicht zu Konflikten führt.

Für Mitgliedsfunktionen verfügen Sie unabhängig davon, ob Sie sie in der Klasse oder außerhalb der Klasse definieren, über eine Funktionsadresse. Wenn mehrere Objekte vorhanden sind, müssen Sie nur Ihre Adresse aufrufen und im Stapelbereich einen Stapelrahmen erstellen.

Wir können also zusammenfassen:Die Mitgliedsvariablen einer Klasse sind alle im Objekt definiert, die Mitgliedsfunktionen der Klasse müssen jedoch nicht im Objekt definiert werden.

Fügen Sie hier eine Bildbeschreibung ein

Klassengröße

class Date
{
    
    
private:
	//声明
	int _year;
	int _month;
	int _day;
public:
	void Init(int year, int month, int day)
	{
    
    
		
		_year = year;
		_month = month;
		_day = day;
	}

	void Print()
	{
    
    
		cout << _year << "-" << _month << "-" << _day << endl;
	}
	
};
class SizeNuLL
{
    
    

};
class Size1NULL
{
    
    
	class Size2NULL
	{
    
    

	};
};
int main()
{
    
    
	cout << sizeof(d1) << endl;//12
	SizeNuLL s1;
	cout << sizeof(s1) << endl;//1
	Size1NULL s2;
	cout << sizeof(s2) << endl;//1
	无成员变量的类,对象大小开一个字节,这个字节不存储有效位
	用来标识的对象存在过
}

Die Berechnung hier berechnet nur Mitgliedsvariablen. Die Berechnungsmethode ist dieselbe wie die Berechnungsmethode der Struktur und es werden die Regeln der Speicherausrichtung verwendet.
Für Klassen ohne Mitgliedsvariablen beträgt die Objektgröße ein Byte. Dieses Byte speichert keine gültigen Bits und wird zur Identifizierung des vorhandenen Objekts verwendet.

dieser Zeiger

class Date
{
    
    
private:
	//声明
	int _year;
	int _month;
	int _day;
public:
	int dd;
	void Init(int year, int month, int day)
	{
    
    
		_year = year;
		_month = month;
		_day = day;
	}

	void Print()
	{
    
    
		cout << _year << "-" << _month << "-" << _day << endl;
	}
	
};
int main()
{
    
    
	Date d1;
	d1.Init(2023, 10, 19);
	d1.Print();
	Date d2;
	d2.Init(2022, 9, 8);
	d2.Print();
}

Fügen Sie hier eine Bildbeschreibung ein
Im obigen Code: Wir beziehen uns nicht auf die Parameter der zugehörigen Objekte in den Parametern der Mitgliedsfunktion. Wie identifizieren wir verschiedene Objekte?
Dieses Problem wird in C++ durch die Einführung dieses Zeigers gelöst, das heißt: Der C++-Compiler fügt jeder „nicht statischen Mitgliedsfunktion“ ein hinzu.Versteckte Zeigerparameter, lassen Sie den Zeiger auf das aktuelle Objekt zeigen (das Objekt, das die Funktion aufruft, wenn die Funktion ausgeführt wird). Über diesen Zeiger wird auf alle „Mitgliedsvariablen“-Operationen im Funktionskörper zugegriffen. Es ist nur so, dass alle Vorgänge für den Benutzer transparent sind, das heißt, der Benutzer muss sie nicht übergeben, der Compiler führt sie automatisch aus.

Fügen Sie hier eine Bildbeschreibung ein

Wenn der Zeiger null ist:

Date* d3 = nullptr;
	//错误的,对象指针为空,this指针也为空
	d3->Init(2023, 10, 20);
	d3->Print();
	Date* d4;
	//错误的,d4没有初始化,指针相当于指向空
	d4->Init(2023, 10, 21);
	d4->Print();

charakteristisch

  1. Der Typ dieses Zeigers: Klassentyp * const, dh in Mitgliedsfunktionen kann diesem Zeiger kein Wert zugewiesen werden.
    Fügen Sie hier eine Bildbeschreibung ein

  2. Kann nur innerhalb einer „Member-Funktion“ verwendet werden

Fügen Sie hier eine Bildbeschreibung ein3. Der This-Zeiger ist im Wesentlichen der formale Parameter der „Member-Funktion“. Wenn das Objekt die Member-Funktion aufruft, wird die Objektadresse als tatsächlicher Parameter an diesen Parameter übergeben. Daher wird dieser Zeiger nicht im Objekt gespeichert.
4. Dieser Zeiger ist der erste implizite Zeigerparameter der „Mitgliedsfunktion“. Im Allgemeinen wird er automatisch vom Compiler über das ECX-Register übergeben und muss nicht vom Benutzer übergeben werden .
5. Der This-Zeiger speichert die entsprechende Mitgliedsfunktion, die aktuell aufgerufen wirddie Adresse des Objekts, also im Stapelrahmen. (Einige Editoren speichern es in Registern, z. B. VS2022)

Zusammenfassen

Die Mitgliedsvariablen einer Klasse sind eigentlich nur Deklarationen, und die Definition wird in der Variablen definiert (wenn ein Klassenobjekt erstellt wird). Die Mitgliedsfunktion befindet sich nicht innerhalb des Klassenobjekts, sie gehört zum öffentlichen Teil, also zu jedem Das Klassenobjekt kann es aufrufen. Der Zeiger funktioniert nicht. Die Initialisierung und das Zeigen auf Null zeigen im Wesentlichen nicht auf ein vorhandenes Klassenobjekt, was zu unklaren Zeigern führt. In der Mitgliedsfunktion wird ein Zeiger „dieser“ ausgeblendet, der anzeigt, dass er auf die Mitgliedsvariable zeigt. Wir können dies beim Schreiben von Code nicht anzeigen. Dieser Schritt wurde automatisch vom Compiler geschrieben und die Variable kann direkt in der Mitgliedsfunktion aufgerufen werden. Dies bedeutet auch, dass dieser Zeiger die vorhandene Mitgliedsvariable nicht finden kann, wenn der Zeiger leer ist.

おすすめ

転載: blog.csdn.net/m0_74068921/article/details/133961898