Résumé des articles suivants :
1. Pour les variables statiques : localisation (conflit de nom), initialisation = 0, partage unique (zone statique) . En particulier, pour les variables membres statiques de classe : (1) Appartiennent à la classe entière et sont accessibles directement via le nom de la classe plutôt que via l'instance (2) Doivent être initialisées, déclarées statiques dans la classe, initialisées en dehors de la classe (statiques). ne peut pas être ajouté)
2. Pour les fonctions membres statiques de classe, (1) il n'y a pas de pointeur this, seules les variables membres statiques et les fonctions membres statiques sont accessibles et ne peuvent pas être déclarées comme fonctions virtuelles (2) Généralement. utilisé dans les sous-classes en multi-threads.
------------------------------------------------------ ------ -------------------------------------------- ------ -------------------------------------------- ------ ---
1. Qu'est-ce que static ?
static est un modificateur très couramment utilisé en C++. Il est utilisé pour contrôler la méthode de stockage et la visibilité des variables.
2. Pourquoi introduire du statique ?
Pour les variables définies à l'intérieur d'une fonction, lorsque le programme est exécuté selon sa définition, le compilateur lui alloue de l'espace sur la pile. Comme nous le savons tous, les fonctions sont allouées sur. la pile L'espace sera libéré à la fin de l'exécution de cette fonction, ce qui pose une question : Si vous souhaitez sauvegarder la valeur de cette variable dans la fonction au prochain appel, comment y parvenir ? La façon la plus simple de penser est de définir une variable globale, mais la définir comme variable globale présente de nombreux inconvénients. L'inconvénient le plus évident est que cela détruit la portée d'accès de cette variable (ce qui rend les variables définies dans cette fonction non seulement contrôlées par). cette fonction).
3. Quand utiliser static ?
Un objet de données doit servir la classe entière plutôt qu'un certain objet, et en même temps, il s'efforce de ne pas détruire l'encapsulation de la classe, qui c'est-à-dire que ce membre doit être caché à l'intérieur de la classe et non visible du monde extérieur.
4. Le mécanisme interne de la statique :
Les données membres statiques doivent exister lorsque le programme démarre. Étant donné que les fonctions sont appelées pendant l'exécution du programme, les données membres statiques ne peuvent pas être allouées et initialisées dans une fonction.
De cette façon, il y a trois emplacements possibles pour son allocation d'espace. L'un est le fichier d'en-tête comme interface externe de la classe, où se trouve la déclaration de classe ; le second est l'implémentation interne de la définition de classe, où se trouve la déclaration de classe ; sont les définitions des fonctions membres de la classe ;la troisième est la déclaration et la définition des données globales d'application avant la fonction main() du programme.
Les données membres statiques doivent réellement allouer de l'espace, elles ne peuvent donc pas être définies dans la déclaration de la classe (seules les données membres peuvent être déclarées). La déclaration de classe déclare uniquement « la taille et les spécifications » d'une classe et n'effectue pas d'allocation de mémoire réelle, il est donc erroné d'écrire une définition dans la déclaration de classe. Il ne peut pas non plus être défini en dehors d'une déclaration de classe dans un fichier d'en-tête, car cela entraînerait sa redéfinition dans plusieurs fichiers sources utilisant la classe.
Static est introduit pour indiquer au compilateur de stocker les variables dans la zone de stockage statique du programme au lieu de l'espace sur la pile. Les membres de données
statiques sont initialisés dans l'ordre dans lequel ils sont définis. lors de l'imbrication de membres statiques, assurez-vous que le membre imbriqué a été initialisé. L'ordre d'élimination est l'ordre inverse de l'initialisation.
5. Avantages du statique :
Il peut économiser de la mémoire car il est commun à tous les objets. Par conséquent, pour plusieurs objets, les données membres statiques ne sont stockées qu'à un seul endroit pour que tous les objets puissent être partagés. La valeur d'une donnée membre statique est la même pour chaque objet, mais sa valeur peut être mise à jour. Tant que la valeur du membre de données statique est mise à jour une fois, tous les objets sont assurés d'accéder à la même valeur mise à jour, ce qui peut améliorer l'efficacité du temps.
6. Lorsque vous référencez des membres de données statiques, utilisez le format suivant :
<Nom de la classe>::<Nom du membre statique>
Si les droits d'accès des données membres statiques sont autorisés (c'est-à-dire les membres publics), les données membres statiques peuvent être référencées dans le programme selon le format ci-dessus.
7. Notes :
(1)La fonction membre statique de la classe appartient à la classe entière plutôt qu'à l'objet de la classe, elle n'a donc pas ce pointeur, qui aboutit à It , ne peut accéder qu'aux données statiques et aux fonctions membres statiques de la classe.
(2) Les fonctions membres statiques ne peuvent pas être définies comme des fonctions virtuelles.
(3) Puisque les membres statiques sont déclarés dans la classe et opèrent en dehors de celle-ci, l'opération de prise de leur adresse est quelque peu spéciale. L'adresse de la variable est un pointeur vers son type de données , et l'adresse de la fonction. tapez C'est un "non-membrepointeur de fonction".
(4) Puisque la fonction membre statique n'a pas ce pointeur, elle est presque équivalente à la fonction non membre. Le résultat est un avantage inattendu : elle devient une fonction de rappel, ce qui permet de combiner C++ et C. basé sur X Intégré au système Window, il a également été appliqué avec succès aux fonctions de thread.
(5)static n'augmente pas la surcharge de temps et d'espace du programme, au contraire, il raccourcit également le temps d'accès de la sous-classe aux membres statiques de la classe parent, économisant ainsi l'espace mémoire de la sous-classe.
(6) Les données membres statiques sont précédées du mot-clé static lorsque
(7)Les données membres statiques sont stockées de manière statique, elles doivent donc être initialisées.
(8) L'initialisation des membres statiques est différente de l'initialisation générale des membres de données :
L'initialisation est effectuée en dehors de la classe, et static n'est pas ajouté devant pour éviter toute confusion avec les variables statiques générales ou des objets ;
Lors de l'initialisation, n'ajoutez pas les caractères de contrôle d'accès private, public, etc. du membre
Lors de l'initialisation, utilisez l'opérateur scope pour indiquer la classe à laquelle il appartient ;
Nous obtenons donc des données statiques Format d'initialisation des membres:
,,,,,,,,,,,, Définir une variable statique dans la sous-classe qui est la même que la classe parent pour protéger l'influence du parent classe. Il y a une chose à noter ici : nous disons que les membres statiques sont partagés par les classes et sous-classes parentes, mais nous avons défini à plusieurs reprises des membres statiques. Cela provoquera-t-il une erreur ? Non, notre compilateur utilise une astuce astucieuse : la modification des noms pour générer des identifiants uniques.
Membres de données statiques
Dans une classe, les membres statiques peuvent réaliser le partage de données entre plusieurs objets, et l'utilisation de membres de données statiques ne détruira pas le principe caché, c'est-à-dire garantira la sécurité. Par conséquent, les membres statiques sont des membres partagés entre tous les objets d'une classe, et non les membres d'un certain objet.
L'utilisation de données membres statiques peut économiser de la mémoire, car elle est commune à tous les objets. Par conséquent, pour plusieurs objets, les données membres statiques ne sont stockées qu'à un seul endroit pour que tous les objets puissent être partagés. La valeur d'une donnée membre statique est la même pour chaque objet, mais sa valeur peut être mise à jour. Tant que la valeur du membre de données statique est mise à jour une fois, tous les objets sont assurés d'accéder à la même valeur mise à jour, ce qui peut améliorer l'efficacité du temps.
L'utilisation et les précautions des données membres statiques sont les suivantes :
1. Ajoutez le mot-clé static avant la définition ou la description des données membres statiques.
2. L'initialisation des membres statiques est différente de l'initialisation générale des membres de données. Le format d'initialisation des membres de données statiques est le suivant :
Cela indique :
(1) L'initialisation est effectuée en dehors de la classe, sans statique devant, pour éviter toute confusion avec des variables ou des objets statiques généraux.
(2) N'ajoutez pas les caractères de contrôle d'accès du membre privés, publics, etc. lors de l'initialisation.
(3) Utilisez l'opérateur scope lors de l'initialisation pour indiquer la classe à laquelle il appartient. Par conséquent, les données membres statiques sont membres de la classe, pas de l'objet.
3. Les données membres statiques sont stockées de manière statique. Elles ont une durée de vie statique et doivent être initialisées.
4. Lorsque vous référencez des membres de données statiques, utilisez le format suivant :
Si l'autorisation d'accès est autorisée (c'est-à-dire les membres publics), les données membres statiques peuvent être référencées dans le programme selon le format ci-dessus.
Fonction membre statique
Les fonctions membres statiques sont les mêmes que les membres de données statiques. Elles sont toutes deux membres statiques de la classe et ne sont pas des membres objets. Par conséquent, les références aux membres statiques n’ont pas besoin d’utiliser des noms d’objet.
Dans l'implémentation d'une fonction membre statique, vous ne pouvez pas référencer directement les membres non statiques décrits dans la classe, mais vous pouvez référencer les membres statiques décrits dans la classe. Si un membre non statique doit être référencé dans une fonction membre statique, il peut être référencé via un objet.
Regardons un exemple :
# include <iostream.h> class Point { public: void output() { } static void init() { } }; void main( void ) { Point pt; pt.init(); pt.output(); }
Il n'y aura aucune erreur dans une compilation comme celle-ci.
Regardez comme ça
#include <iostream.h> class Point { public: void output() { } static void init() { } }; void main( void ) { Point::output(); }
Une compilation comme celle-ci provoquera une erreur, Message d'erreur : illégal appel du non statique membre fonction, pourquoi ?
Car lorsqu'un objet spécifique d'une classe n'est pas instancié, la classe ne se voit pas allouer d'espace mémoire.
D'accord, regardez l'exemple suivant :
#include <iostream.h> class Point { public: void output() { } static void init() { } }; void main( void ) { Point::init(); }
Il n'y aura aucune erreur de compilation pour le moment, car lorsque la classe est définie, ses données statiques et ses fonctions membres l'ont A zone mémoire qui n’appartient à aucun objet spécifique de la classe.
D'accord, regardez l'exemple suivant :
#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(); }
Erreur de compilation :
illégal référence aux données membre 'Point::x' dans une référence statique membre fonction
illégal aux données membre 'Point::y' dans un membre fonction
statique dans un membre statique Le Le membre de données a été incorrectement référencé dans la fonction.
C'est toujours le même problème. Les membres statiques (fonctions) n'appartiennent à aucun objet spécifique, il y a donc déjà une zone mémoire avant que l'objet spécifique de la classe ne soit déclaré. > Et maintenant, les données membres non statiques n'ont pas alloué d'espace mémoire, donc l'appel ici est erroné, tout comme utiliser une variable à l'avance sans la déclarer.
C'est-à-dire que les variables membres non statiques ne peuvent pas être référencées dans les fonctions membres statiques.
D'accord, regardons l'exemple ci-dessous :
#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自变量这一行为。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!