Zusammenfassung der folgenden Artikel:
1. Für statische Variablen: Lokalisierung (Namenskonflikt), Initialisierung = 0, eindeutige Freigabe (statischer Bereich). Insbesondere für statische Mitgliedsvariablen der Klasse: (1) Gehören zur gesamten Klasse und können direkt über den Klassennamen statt über die Instanz aufgerufen werden. (2) Muss initialisiert, innerhalb der Klasse als statisch deklariert und außerhalb der Klasse initialisiert werden (statisch). kann nicht hinzugefügt werden)
2. Für statische Mitgliedsfunktionen der Klasse (1) gibt es keinen Zeiger, es kann nur auf statische Mitgliedsvariablen und statische Mitgliedsfunktionen zugegriffen werden und sie können nicht als virtuelle Funktionen deklariert werden (2) Im Allgemeinen Wird in Unterklassen in Multithreads verwendet.
---------------- ------ -------------------------------------------- ------ -------------------------------------------- ------ ---
1. Was ist statisch?
statisch ist ein sehr häufig verwendeter Modifikator in C++. Er wird verwendet, um die Speichermethode und Sichtbarkeit von Variablen zu steuern.
2. Warum statische Variablen einführen?
Für Variablen, die innerhalb einer Funktion definiert sind, weist der Compiler bei der Ausführung des Programms Platz auf dem Stapel zu. Wie wir alle wissen, werden Funktionen zugewiesen der Stapel Der Speicherplatz wird am Ende der Ausführung dieser Funktion freigegeben, was die Frage aufwirft: Wenn Sie den Wert dieser Variablen in der Funktion beim nächsten Aufruf speichern möchten, wie erreichen Sie dies? Am einfachsten ist es, eine globale Variable zu definieren. Die Definition als globale Variable hat jedoch viele Nachteile. Der offensichtlichste Nachteil besteht darin, dass der Zugriffsbereich dieser Variablen zerstört wird (wodurch die in dieser Funktion definierten Variablen nicht nur von gesteuert werden). diese Funktion).
3. Wann sollte statisch verwendet werden?
Ein Datenobjekt muss die gesamte Klasse und nicht ein bestimmtes Objekt bedienen, und gleichzeitig ist es bestrebt, die Kapselung der Klasse nicht zu zerstören Das heißt, es erfordert, dass dieses Mitglied innerhalb der Klasse verborgen ist und für die Außenwelt nicht sichtbar ist.
4. Der interne Mechanismus der Statik:
Statische Datenelemente müssen vorhanden sein, wenn das Programm ausgeführt wird. Da Funktionen aufgerufen werden, während das Programm ausgeführt wird, können statische Datenelemente nicht innerhalb einer Funktion zugewiesen und initialisiert werden.
Auf diese Weise gibt es drei mögliche Orte für die Speicherplatzzuweisung. Einer ist die Header-Datei als externe Schnittstelle der Klasse, der zweite ist die interne Implementierung der Klassendefinition sind die Definitionen der Mitgliedsfunktionen der Klasse; die dritte ist die globale Datendeklaration und -definition vor der Funktion main() des Programms.
Statische Datenelemente müssen tatsächlich Speicherplatz zuweisen, daher können sie nicht in der Deklaration der Klasse definiert werden (es können nur Datenelemente deklariert werden). Die Klassendeklaration deklariert nur die „Größe und Spezifikationen“ einer Klasse und führt keine tatsächliche Speicherzuweisung durch. Daher ist es falsch, eine Definition in die Klassendeklaration zu schreiben. Sie kann auch nicht außerhalb einer Klassendeklaration in einer Header-Datei definiert werden, da dies dazu führen würde, dass sie in mehreren Quelldateien, die die Klasse verwenden, neu definiert wird.
Static wird eingeführt, um den Compiler anzuweisen, Variablen im statischen Speicherbereich des Programms statt im Speicherplatz auf dem Stapel zu speichern. Beachten Sie Folgendes: Statische Datenelemente werden in der Reihenfolge initialisiert, in der sie definiert sind Stellen Sie beim Verschachteln statischer Elemente sicher, dass das verschachtelte Element initialisiert wurde. Die Reihenfolge der Eliminierung ist die umgekehrte Reihenfolge der Initialisierung.
Es kann Speicher gespart werden, da es allen Objekten gemeinsam ist. Daher werden statische Datenelemente für mehrere Objekte nur an einem Ort gespeichert, damit alle Objekte sie gemeinsam nutzen können. Der Wert eines statischen Datenelements ist für jedes Objekt derselbe, sein Wert kann jedoch aktualisiert werden. Solange der Wert des statischen Datenelements einmal aktualisiert wird, ist garantiert, dass alle Objekte auf denselben aktualisierten Wert zugreifen, was die Zeiteffizienz verbessern kann.
<Klassenname>::<Statischer Elementname> Wenn die Zugriffsrechte der statischen Datenelemente zulässig sind (d. h. öffentliche Mitglieder), können die statischen Datenelemente im Programm gemäß dem oben genannten Format referenziert werden.
7. Hinweise:
(1)Die statische Mitgliedsfunktion der Klasse gehört zur gesamten Klasse und nicht zum Objekt der Klasse, also nicht Dieser Zeiger führt dazu, dass nur auf statische Daten und statische Mitgliedsfunktionen der Klasse zugreifen kann.
(2) Statische Memberfunktionen können nicht als virtuelle Funktionen definiert werden.
(3) Da statische Mitglieder in der Klasse deklariert werden und außerhalb dieser operieren, ist die Operation, ihre Adresse zu übernehmen, etwas Besonderes. Die Variablenadresse ist ein Zeiger auf ihren Datentyp und die Funktionsadresse Typ Es ist ein „NichtmitgliedFunktionszeiger“.
(4) Da die statische Member-Funktion diesen Zeiger nicht hat, entspricht sie fast der Nicht-Member-Funktion. Das Ergebnis ist ein unerwarteter Vorteil: Sie wird zu einer Rückruffunktion, die es uns ermöglicht, C++ und C zu kombinieren -basiertes X Es ist in das Windows-System integriert und wurde auch erfolgreich auf Thread-Funktionen angewendet.
(5) static erhöht nicht den Zeit- und Platzaufwand des Programms, sondern verkürzt im Gegenteil auch die Zugriffszeit der Unterklasse auf die statischen Mitglieder der übergeordneten Klasse, wodurch der Speicherplatz der Unterklasse gespart wird.
(6) Statischen Datenelementen wird bei
(7)Statische Datenelemente werden statisch gespeichert und müssen daher initialisiert werden.
(8) Die Initialisierung statischer Elemente unterscheidet sich von der Initialisierung allgemeiner Datenelemente:
Die Initialisierung erfolgt außerhalb der Klasse und statische wird nicht vorangestellt, um Verwechslungen mit allgemeinen statischen Variablen zu vermeiden oder Objekte;
Fügen Sie beim Initialisieren nicht die Zugriffskontrollzeichen privat, öffentlich usw. des Mitglieds hinzu.
Verwenden Sie beim Initialisieren den Bereichsoperator , um die Klasse anzugeben, zu der es gehört. So erhalten wir statisches Datenformat der Mitgliedsinitialisierung:
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, mit ,,,,,, Definieren Sie eine statische Variable in der Unterklasse, die mit der übergeordneten Klasse identisch ist, um den Einfluss der übergeordneten Klasse abzuschirmen. Hier ist eines zu beachten: Wir sagen, dass statische Mitglieder von übergeordneten Klassen und Unterklassen gemeinsam genutzt werden, aber wir haben wiederholt statische Mitglieder definiert. Wird dies einen Fehler verursachen? Nein, unser Compiler verwendet einen cleveren Trick: Namensverfälschung, um eindeutige Bezeichner zu generieren.
Statische Datenmitglieder
In einer Klasse können statische Mitglieder den Datenaustausch zwischen mehreren Objekten realisieren, und die Verwendung statischer Datenmitglieder zerstört nicht das verborgene Prinzip, dh die Gewährleistung der Sicherheit. Daher sind statische Mitglieder Mitglieder, die von allen Objekten einer Klasse gemeinsam genutzt werden, nicht Mitglieder eines bestimmten Objekts.
Die Verwendung statischer Datenelemente kann Speicher sparen, da diese allen Objekten gemeinsam sind. Daher werden statische Datenelemente bei mehreren Objekten nur an einem Ort gespeichert, damit alle Objekte sie gemeinsam nutzen können. Der Wert eines statischen Datenelements ist für jedes Objekt derselbe, sein Wert kann jedoch aktualisiert werden. Solange der Wert des statischen Datenelements einmal aktualisiert wird, ist garantiert, dass alle Objekte auf denselben aktualisierten Wert zugreifen, was die Zeiteffizienz verbessern kann.
Die Verwendung und Vorsichtsmaßnahmen für statische Datenelemente sind wie folgt:
1. Fügen Sie das Schlüsselwort static vor der Definition oder Beschreibung statischer Datenelemente hinzu.
2. Die Initialisierung statischer Elemente unterscheidet sich von der Initialisierung allgemeiner Datenelemente. Das Format der Initialisierung statischer Datenelemente lautet wie folgt:
Dies bedeutet:
(1) Die Initialisierung wird außerhalb der Klasse ohne statische Vorgänge durchgeführt, um Verwechslungen mit allgemeinen statischen Variablen oder Objekten zu vermeiden.
(2) Fügen Sie während der Initialisierung nicht die Zugriffskontrollzeichen „Privat“, „Öffentlich“ usw. des Mitglieds hinzu.
(3) Verwenden Sie den Bereichsoperator während der Initialisierung, um die Klasse anzugeben, zu der er gehört. Daher sind statische Datenmitglieder Mitglieder der Klasse, nicht des Objekts.
3. Statische Datenelemente werden statisch gespeichert. Sie haben eine statische Lebensdauer und müssen initialisiert werden.
4. Verwenden Sie beim Verweisen auf statische Datenelemente das folgende Format:
Wenn die Zugriffsberechtigung zulässig ist (d. h. öffentliche Mitglieder), auf die statischen Datenmitglieder kann im Programm gemäß dem oben genannten Format verwiesen werden.
Statische Mitgliedsfunktionen
Statische Mitgliedsfunktionen sind dasselbe wie statische Datenmitglieder. Sie sind beide statische Mitglieder der Klasse und keine Objektmitglieder. Daher müssen Verweise auf statische Elemente keine Objektnamen verwenden.
Bei der Implementierung einer statischen Elementfunktion können Sie nicht direkt auf die in der Klasse beschriebenen nicht statischen Elemente verweisen, Sie können jedoch auf die in der Klasse beschriebenen statischen Elemente verweisen. Wenn in einer statischen Member-Funktion auf einen nicht statischen Member verwiesen werden muss, kann dieser über ein Objekt referenziert werden.
Sehen wir uns ein Beispiel an:
# include <iostream.h> class Point { public: void output() { } static void init() { } }; void main( void ) { Point pt; pt.init(); pt.output(); }
Beim Kompilieren wie diesem treten keine Fehler auf.
Sieht so aus
#include <iostream.h> class Point { public: void output() { } static void init() { } }; void main( void ) { Point::output(); }
Eine solche Kompilierung führt zu einem Fehler, Fehlermeldung: illegal Anruf von nichtstatisches Mitglied Funktion, warum?
Denn wenn ein bestimmtes Objekt einer Klasse nicht instanziiert wird, wird der Klasse kein Speicherplatz zugewiesen.
Okay, schauen Sie sich das folgende Beispiel an:
#include <iostream.h> class Point { public: void output() { } static void init() { } }; void main( void ) { Point::init(); }
Zu diesem Zeitpunkt wird es keine Fehler bei der Kompilierung geben, denn wenn die Klasse definiert ist, haben ihre statischen Daten und Mitgliedsfunktionen A Speicherbereich, der zu keinem bestimmten Objekt der Klasse gehört.
Okay, schauen Sie sich das folgende Beispiel an:
#include <iostream.h> class Point { public: void output() { } static void init() { x = 0; y = 0; } private: int x; int y; }; void main( void ) { Point::init(); }
Kompilierungsfehler:
illegal Verweis auf Daten member 'Point::x' in einer statischen member Funktion
illegale Referenz auf Daten Mitglied 'Point::y' in einem statischen Mitglied Funktion
in einem statischen Mitglied The Datenmember wurden in der Funktion falsch referenziert. Es ist immer noch das gleiche Problem. Statische Member (Funktionen) gehören zu keinem bestimmten Objekt, daher gibt es bereits einen Speicherbereich, bevor das spezifische Objekt der Klasse deklariert wird > Und jetzt haben nicht-statische Datenelemente keinen Speicherplatz zugewiesen, daher ist der Aufruf hier falsch, genau wie die Verwendung einer Variablen im Voraus, ohne sie zu deklarieren.
Das heißt, nicht statische Mitgliedsvariablen können in statischen Mitgliedsfunktionen nicht referenziert werden.
Okay, schauen wir uns das Beispiel unten an:
#include <iostream.h>class Point{public:void output(){ x = 0; y = 0; init(); }static void init(){ }private:int x;int y;};void main( void ){Point::init();}
好的,这样就不会有任何错误。这最终还是一个内存模型的问题,
任何变量在内存中有了自己的空间后,在其他地方才能被调用,否则就会出错。
好的再看看下面的例子:
#include <iostream.h> class Point { public: void output() { } static void init() { x = 0; y = 0; } private: static int x; static int y; }; void main( void ) { Point::init(); }
编译:
Linking...
test.obj : error LNK2001: unresolved external symbol "private: static int Point::y"
test.obj : error LNK2001: unresolved external symbol "private: static int Point::x"
Debug/Test.exe : fatal error LNK1120: 2 unresolved externals
执行 link.exe 时出错.
可以看到编译没有错误,连接错误,这又是为什么呢?
这是因为静态的成员变量要进行初始化,可以这样:
#include <iostream.h> class Point { public: void output() { } static void init() { x = 0; y = 0; } private: static int x; static int y; }; int Point::x = 0; int Point::y = 0; void main( void ) { Point::init(); }
在静态成员数据变量初始化之后就不会出现编译错误了。
再看看下面的代码:
#include <iostream.h> class Point { public: void output() { } static void init() { x = 0; y = 0; } private: static int x; static int y; }; void main( void ) { }
编译没有错误,为什么?
即使他们没有初始化,因为我们没有访问x,y,所以编译不会出错。
C++会区分两种类型的成员函数:静态成员函数和非静态成员函数。这两者之间的一个重大区别是,静态成员函数不接受隐含的this自变量。所以,它就无法访问自己类的非静态成员。
在某些条件下,比如说在使用诸如pthread(它不支持类)此类的多线程库时,就必须使用静态的成员函数,因为其地址同C语言函数的地址兼容。这种铜限制就迫使程序员要利用各种解决办法才能够从静态成员函数访问到非静态数据成员。
第一个解决办法是声明类的所有数据成员都是静态的。运用这种方式的话,静态的成员函数就能够直接地访问它们,例如:
class Singleton { public: static Singleton * instance(); private: Singleton * p; static Lock lock; }; Singleton * Singleton::instance() { lock.getlock(); // fine, lock is static if (!p) p=new Singleton; lock.unlock(); return p; }
这种解决方法不适用于需要使用非静态数据成员的类。
访问非静态数据成员
将参照传递给需要考量的对象能够让静态的成员函数访问到对象的非静态数据:
class A { public: static void func(A & obj); intgetval() const; // non-static member function private: intval; };
静态成员函数func()会使用参照obj来访问非静态成员val。
voidA::func(A & obj) { int n = obj.getval(); }
将一个参照或者指针作为静态成员函数的自变量传递,就是在模仿自动传递非静态成员函数里this自变量这一行为。
Das obige ist der detaillierte Inhalt vonDie Rolle des statischen Schlüsselworts in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!