Klassen und Objekte [1] Einführung

Einführung (erstes Verständnis von objektorientiert)

Die C-Sprache ist prozessorientiert und konzentriert sich auf den Prozess, analysiert die Schritte zur Lösung des Problems und löst das Problem Schritt für Schritt durch Funktionsaufrufe.
C ++ basiert auf der Objektorientierung, konzentriert sich auf das Objekt und teilt eine Sache in verschiedene Objekte auf Dabei wird auf die Interaktion zwischen Objekten zurückgegriffen.

Beispielsweise soll der Vorgang des Wäschewaschens für die prozessorientierte C-Sprache Schritt für Schritt entsprechend der Logik des Waschprozesses implementiert werden: Es werden höchstens mehrere Schritte zum Einbringen von Waschmittel in eine Funktion
Fügen Sie hier eine Bildbeschreibung ein
gekapselt, und a Die Schleife ist für mehrere Waschvorgänge geschrieben. Kurz gesagt, es zielt auf den Prozess des Wäschewaschens ab.

Für objektorientiertes C++ kann der Prozess des Wäschewaschens jedoch durch die Interaktion zwischen mehreren gekapselten Objekten implementiert werden. Es ist beispielsweise in Personen, Kleidung, Waschmittel und Waschmaschine unterteilt: Zum
Fügen Sie hier eine Bildbeschreibung ein
Waschen von Kleidung müssen lediglich Kleidung und Waschmittel in die Waschmaschine gegeben werden, und die Waschmaschine kann den Vorgang ausführen. Einige Waschmaschinenobjekte können auch automatisch Waschmittel hinzufügen. Zu diesem Zeitpunkt ist das Waschmittel ein internes Objekt der Waschmaschine. Kurz gesagt, es zielt auf die Gegenstände ab, die beim Wäschewaschen beteiligt sind.

Es ist nicht schwer festzustellen, dass der objektorientierte Betriebsprozess einfacher und effizienter ist als der prozessorientierte Betriebsprozess. Mit anderen Worten: Die objektorientierte Programmierung ist eine relativ fortgeschrittene Programmiermethode.

Klassen und Objekte

In der C-Sprachstruktur können nur Variablen definiert werden. In C++ können in der Struktur nicht nur Variablen, sondern auch Funktionen definiert werden:

struct Stack
{
    
    
	int* _data;
	int _top;
	int _capacity;

	void init();	
	void push();
	void pop();
	void destory();
};

Der in der C-Sprache implementierte Stapel hat nur Variablen in der Struktur, und die Variablen in der Struktur werden durch Funktionen manipuliert, während die C++-Stapelstruktur Funktionen definieren kann, bei denen es sich tatsächlich um eine Klasse handelt. Struct kann zum Definieren von Klassen verwendet werden, und in C++ gibt es ein spezielles Schlüsselwort classzum Definieren von Klassen:

Definition

Das Format einer Klassendefinitionsklasse ist wie folgt:

class Classname
{
    
    
	//类的主体(成员变量与成员函数)
};

class ist das Schlüsselwort zum Definieren der Klasse, ClassName ist der Name der Klasse und {} ist der Hauptteil der Klasse. Beachten Sie, dass das Semikolon nach dem Ende der Klassendefinition nicht weggelassen werden darf.
Der Inhalt des Klassenkörpers wird als Mitglieder der Klasse bezeichnet: Variablen in der Klasse werden als Attribute oder Mitgliedsvariablen der Klasse bezeichnet; Funktionen in der Klasse werden als Methoden oder Mitgliedsfunktionen der Klasse bezeichnet.

Beschränkung und Kapselung des Klassenzugriffs

Das Kombinieren der Eigenschaften und Methoden eines Objekts mit einer Klasse ist eine Kapselung. Durch den Zugriff auf die Details der verborgenen Eigenschaften und Methoden wird dem Benutzer nur die Schnittstelle bereitgestellt, was die Verwendung der Klasse für den Benutzer erleichtert:

Es gibt drei Zugriffsqualifizierer: public(öffentlich), protected(geschützt), private(privat):

class Classname
{
    
    
public:
	//公共权限:类内可以访问,类外可以访问;
protected:
	//保护权限:类内可以访问,类外不可以访问(子类可以访问);
private:
	//私有权限:类内可以访问,类外不可以访问(子类不可以访问);
};

Es ist nicht schwer herauszufinden, dass die Mitgliedsfunktionen der Klasse im Allgemeinen in der öffentlichen Domäne und die Mitgliedsvariablen in der privaten Domäne platziert werden, da eine Klasse eine Schnittstelle für den Benutzer bereitstellen und Attribute verbergen muss.

was man beachten muss ist:

  1. Der Bereich der Zugriffsrechte beginnt an der Position, an der das Zugriffsqualifikationsmerkmal erscheint, bis zum nächsten Zugriffsqualifikationsmerkmal. Wenn dahinter kein Zugriffsqualifikationsmerkmal steht, erreicht der Geltungsbereich }, also das Ende der Klasse .
  2. Die Standardzugriffsberechtigung der Klasse ist privat und die Struktur ist öffentlich (da die Struktur mit C kompatibel ist).

Zwei Möglichkeiten der Klassendefinition

Beim Definieren einer Klasse gibt es zwei Möglichkeiten: Die Deklaration und Definition der Funktion werden zusammen in der Klasse platziert oder die Deklaration und Definition der Funktion werden getrennt, die Deklaration wird in der Klasse platziert und die Funktionsdefinition wird in der Klasse platziert .cpp-Datei:

Es ist zu beachten, dass, wenn eine Mitgliedsfunktion in einer Klasse definiert ist, diese Funktion standardmäßig als Inline-Funktion betrachtet wird (hier schreiben Sie einfach ein Beispiel für eine Datumsklasse):

class Date
{
    
    
public:

	void InitDate(int year = 2023, int month = 2, int day = 10)
	{
    
    
		_year = year;
		_month = month;
		_day = day;
	}
	Date& AddDate(int day)
	{
    
    
		_day += day;
		while (_day > GetMonthDay(_year, _month))
		{
    
    
			_day -= GetMonthDay(_year, _month);
			_month++;
			if (_month > 12)
			{
    
    
				_year++;
				_month = 1;
			}
		}
		return *this;
	}
	int GetMonthDay(int year, int month)
	{
    
    
		int monthdays[13] = {
    
     0,31,28,31,30,31,30,31,31,30,31,30,31 };
		if ((month == 2) && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
		{
    
    
			monthdays[month] = 29;
		}
		return monthdays[month];
	}
private:
	int _year;
	int _month;
	int _day;
};

Wenn die Deklaration von der Definition getrennt ist, ist die Definition beim Definieren der Funktion erforderlich 类名::函数名:

class Date
{
    
    
public:
    void InitDate(int year = 2023, int month = 2, int day = 10);
	Date& AddDate(int day);
	int GetMonthDay(int year, int month);
private:
	int _year;
	int _month;
	int _day;
};

void Date::InitDate(int year = 2023, int month = 2, int day = 10)
{
    
    
	_year = year;
	_month = month;
	_day = day;
}
Date& Date::AddDate(int day)
{
    
    
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
    
    
		_day -= GetMonthDay(_year, _month);
		_month++;
		if (_month > 12)
		{
    
    
			_year++;
			_month = 1;
		}
	}
	return *this;
}
int Date::GetMonthDay(int year, int month)
{
    
    
	int monthdays[13] = {
    
     0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if ((month == 2) && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
	{
    
    
		monthdays[month] = 29;
	}
	return monthdays[month];
}

Beim Definieren einer Klasse wird empfohlen, die zweite Methode zu verwenden und öffentliche Mitgliedsfunktionen vor privaten Mitgliedsvariablen zu definieren .

Klasseninstanziierung und Klassenobjektgröße

Die oben definierte Klasse ist nur ein Klassentyp, der dem Bauplan des Hauses entspricht und keinen Speicherplatz freigibt.
Der Vorgang des Erstellens eines Objekts mit einer Klasse wird als Instanziierung der Klasse bezeichnet. Das instanziierte Objekt belegt einen bestimmten Speicherplatz.
Der Klassenname ist der Typname des Klassentyps. Ein Klassentyp kann mehrere Klassenobjekte instanziieren, beispielsweise die Datumsklasse oben:

int main()
{
    
    
    //实例化三个类对象
	Date d1;
	Date d2;
	Date d3;
	//对三个类对象调用其成员函数进行初始化
	d1.InitDate();
	d2.InitDate(2023, 5, 14);
	d3.InitDate(2000, 1, 1);
	return 0;
}

Der obige Inhalt ist nicht schwer zu verstehen, aber wie sollte die Größe der Klasse berechnet werden, da die Mitgliedsfunktionen auch im Klassenobjekt enthalten sind?
Im C-Sprachteil haben wir gelernt, wie man die Größe der Struktur berechnet, und die Struktur folgt bei der Speicherzuweisung den Regeln der Speicherausrichtung:
Klicken Sie auf mich, um die detaillierte Erklärung der Speicherausrichtung der Struktur zu sehen

Die Größe der Klasse folgt ebenfalls den Regeln der Speicherausrichtung. Bei Mitgliedsfunktionen nimmt sie jedoch nicht den Platz des Klassenobjekts ein, obwohl sie in der Klasse gekapselt ist. Im Codesegment wird nur eine Kopie der Mitgliedsfunktion gespeichert, und im Klassenobjekt werden nur Mitgliedsvariablen gespeichert :

int main()
{
    
    
	Date d1;
	cout << sizeof(d1) << endl;
	return 0;
}

Fügen Sie hier eine Bildbeschreibung ein
Daher umfasst die Größe des oben genannten Date-Klassenobjekts d1 nur drei Mitgliedsvariablen vom Typ int, und die Größe beträgt je nach Speicherausrichtung 12 Byte.

Für die leere Klasse gibt es einen Byte-Speicherplatz zur Unterscheidung.

dieser Zeiger

Wie oben erwähnt, sind private Mitgliedsvariablen innerhalb der Klasse zugänglich. Beispielsweise sind die Ergebnisse beim Hinzufügen von Tagen zu verschiedenen Klassen unterschiedlich:

int main()
{
    
    
	//类实例化
	Date d1;
	Date d2;
	//类初始化
	d1.InitDate();
	d2.InitDate(2023, 5, 14);
	//不同的日期类对象+100天
	d1.AddDate(100);
	d2.AddDate(100);
	return 0;
}

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Woher weiß die Mitgliedsfunktion, welches Objekt aufgerufen wird, wie sie die Mitgliedsvariablen der Klasse erhält und sie bearbeitet?

Dies liegt daran , dass wir beim Aufrufen einer Member-Funktion tatsächlich deren Member-Funktion für ein Objekt aufrufen. Es gibt tatsächlich einen impliziten thisZeiger in der Parameterliste der Mitgliedsfunktion des Klassenobjekts, der sich auf der linken Seite der Parameterliste befindet .
Dieser Zeiger ist der Zeiger des Objekts, das die Mitgliedsfunktion aufruft, und seine Funktion besteht darin, der Mitgliedsfunktion beim Aufrufen der Mitgliedsvariablen zu helfen. Tatsächlich ist die obige AddDate-Funktion im Wesentlichen folgende:

//Date& Date::AddDate(Date *const this, int day); //错误代码:this指针必须隐式传参

Innerhalb der Funktion wird der Zugriff auf Mitgliedsvariablen wie folgt implementiert:

{
    
    
	this->_day += day;
	while (this->_day > GetMonthDay(this->_year, this->_month))
	{
    
    
		this->_day -= GetMonthDay(this->_year, this->_month);
		++(this->_month);
		if (this->_month > 12)
		{
    
    
			++(this->_year);
			this->_month = 1;
		}
	}
	return *this;
}

Obwohl es möglich ist, den Zeiger this explizit für den Zugriff auf Mitgliedsvariablen zu verwenden, ist ein solcher Code hässlich und nicht prägnant.

Die Eigenschaften dieses Zeigers:

  1. Der Typ dieses Zeigers: Klassentyp * const, d. h. in Mitgliedsfunktionen kann dieser Zeiger nicht zugewiesen werden;
  2. Kann nur innerhalb von Mitgliedsfunktionen verwendet werden;
  3. 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 den This-Formalparameter übergeben. Der This-Zeiger wird also 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.

Zusammenfassen

In diesem Artikel erhalten Sie ein vorläufiges Verständnis von Klassen und Objekten, einschließlich Definition, Instanziierung und diesem Zeiger. Als nächstes werden wir weiterhin das relevante Wissen über Klassen und Objekte ausführlich vorstellen. Ich hoffe, Sie werden weiterhin aufmerksam sein.

Wenn Sie der Meinung sind, dass ich einen bestimmten Teil nicht klar dargelegt habe oder dass bei einem bestimmten Teil ein Problem vorliegt, können Sie dies gerne im Kommentarbereich ansprechen

Wenn dieser Artikel für Sie hilfreich ist, hoffe ich, dass er mit einem Klick verknüpft wird

Ich hoffe, gemeinsam mit Ihnen Fortschritte zu machen

Supongo que te gusta

Origin blog.csdn.net/weixin_73450183/article/details/130549401
Recomendado
Clasificación