Les constantes définies avec const voient leur espace libéré après avoir dépassé leur portée, tandis que les constantes statiques définies avec static ne libèrent pas leur espace de stockage après l'exécution de la fonction.

static signifie statique. Les fonctions membres statiques et les variables membres statiques d'une classe sont associées à la classe, et non à des objets spécifiques de la classe. Même sans objet spécifique, les fonctions membres statiques et les variables membres de la classe peuvent être appelées. Généralement, une fonction statique d'une classe est presque une fonction globale, sauf que sa portée est limitée au fichier qui la contient.

En C++, les variables membres statiques ne peuvent pas être initialisées à l'intérieur de la classe. À l'intérieur de la classe, il n'y a qu'une déclaration ; la définition doit être en dehors du corps de définition de la classe, généralement initialisée dans le fichier d'implémentation de la classe, par exemple :double Account::Rate = 2.25;

Le mot-clé static ne peut être utilisé que dans la déclaration à l'intérieur du corps de définition de la classe ; il ne peut pas être marqué comme static lors de la définition.

En C++, les variables membres const ne peuvent pas non plus être initialisées au niveau de la définition de la classe ; elles ne peuvent être initialisées que via la liste d'initialisation du constructeur, et un constructeur doit exister.

Un membre de données const n'est constant que pendant la durée de vie d'un objet particulier, mais il est variable pour l'ensemble de la classe. Comme une classe peut créer plusieurs objets, différents objets peuvent avoir des valeurs différentes pour leurs membres de données const. Par conséquent, les membres de données const ne peuvent pas être initialisés dans la déclaration de classe, car lorsqu'un objet de la classe n'a pas encore été créé, le compilateur ne sait pas quelle est la valeur du membre de données const.

L'initialisation des membres de données const ne peut se faire que dans la liste d'initialisation du constructeur de la classe. Pour établir une constante qui reste constante dans toute la classe, vous devez utiliser une constante enum dans la classe, ou static const.

class Test{ public: Test():a(0){} enum {size1=100,size2=200}; private: const int a;//Ne peut être initialisé que dans la liste d'initialisation du constructeur static int b;//Définir et initialiser dans le fichier d'implémentation de la classe conststatic int c;//Identique à static const int c; }; int Test::b=0;//les variables membres static ne peuvent pas être initialisées dans la liste d'initialisation du constructeur car elles n'appartiennent pas à un objet spécifique. cosnt intTest::c=0;//Remarque : lors de l'affectation d'une valeur à une variable membre static, le modificateur static n'est pas nécessaire, mais const doit être ajouté.

Le principal objectif des fonctions membres const est d'empêcher les fonctions membres de modifier le contenu de l'objet. C'est-à-dire qu'une fonction membre const ne peut pas modifier les valeurs des variables membres, mais elle peut accéder aux variables membres. Lorsqu'une fonction membre est appelée sur un objet const, cette fonction ne peut être qu'une fonction membre const.

Le principal objectif des fonctions membres statiques est de servir de fonctions globales dans la portée de la classe. Elles ne peuvent pas accéder aux membres de données non statiques de la classe. Les fonctions membres statiques d'une classe n'ont pas de pointeur this, ce qui entraîne :

  • 1. Ne peut pas accéder directement aux variables membres non statiques de la classe ni appeler des fonctions membres non statiques.
  • 2. Ne peut pas être déclarée comme virtual.

Sur l'initialisation des membres static, const, static const et const static

1. Initialisation des membres const dans une classe :

Lors de la création d'un const dans une classe, vous ne pouvez pas lui donner de valeur initiale.

class foo{ public: foo():i(100){} private: const int i=100;//erreur!!! }; //Ou l'initialiser de cette façon foo::foo():i(100){}

2. Initialisation des membres statiques dans une classe :

Les variables statiques d'une classe appartiennent à la classe, et non à un objet spécifique. Elles n'ont qu'une seule copie pendant toute l'exécution du programme. Par conséquent, elles ne peuvent pas être initialisées lors de la définition d'un objet ; c'est-à-dire qu'elles ne peuvent pas être initialisées avec un constructeur. La méthode d'initialisation correcte est :

data type class name::static data member name = value;
class foo{ public: foo(); private: staticint i; }; intfoo::i=20;

Cela indique :

  • 1. L'initialisation est effectuée en dehors du corps de la classe, et static n'est pas ajouté devant, pour éviter toute confusion avec les variables ou objets statiques ordinaires.
  • 2. Lors de l'initialisation, n'ajoutez pas les spécificateurs de contrôle d'accès du membre tels que private, public, etc.
3. Lors de l'initialisation, utilisez l'opérateur de résolution de portée pour indiquer la classe à laquelle il appartient. Par conséquent, les membres de données statiques sont des membres de la classe, et non des membres d'un objet.

3. Initialisation des membres static const et const static dans une classe

Ces deux façons d'écrire ont le même effet. Pour faciliter la mémorisation, une seule méthode générale d'initialisation est expliquée ici :

class Test{ public: static const int mask1; conststatic int mask2; }; constTest::mask1=0xffff; constTest::mask2=0xffff; // Leur initialisation n'est pas différente, bien que l'une soit une constante statique et l'autre une statique constante. Les éléments statiques sont stockés dans la zone des variables globales ; en fait, le résultat final est le même. Différents compilateurs peuvent les gérer différemment, mais le résultat final est le même.

Exemple complet

Exemple

#ifdef A_H_ #define A_H_ #include <iostream> usingnamespace std; class A{ public: A(int a); staticvoid print();//Fonction membre statique private: static int aa;//Déclaration d'un membre de données statique staticconst int count;//Membre de données statique constant (peut être initialisé dans le constructeur) const int bb;//Membre de données constant }; int A::aa=0;//Définition + initialisation d'un membre statique const int A::count=25;//Définition + initialisation d'un membre statique constant A::A(int a):bb(a){//Initialisation d'un membre constant aa+=1; } void A::print(){ cout<<"count="<<count<<endl; cout<<"aa="<<aa<<endl; } #endif void main(){ A a(10); A::print();//Accès à une fonction membre statique via la classe a.print();//Accès à une fonction membre statique via un objet }

Emplacement de l'initialisation

Les membres statiques ne peuvent pas être initialisés dans la définition de la classe (sauf pour int). Ils ne peuvent pas être initialisés dans le fichier d'en-tête.

Par exemple, si myclass.h est défini, il est généralement initialisé dans myclass.cpp.


Membres statiques des classes C++ (static)

Les membres statiques sont proposés pour résoudre le problème du partage de données. Il existe de nombreuses façons de réaliser le partage, comme définir des variables globales ou des objets, par exemple. Cependant, les variables globales ou les objets ont des limites. Dans ce chapitre, nous discutons principalement de l'utilisation de membres statiques d'une classe pour réaliser le partage de données.

Membre de données statique

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 rompt pas le principe de masquage, garantissant ainsi la sécurité. Par conséquent, les membres statiques sont des membres partagés par tous les objets de la classe, et non des membres d'un objet particulier.

L'utilisation de membres de données statiques peut économiser de la mémoire, car ils sont communs à tous les objets. Par conséquent, pour plusieurs objets, les membres de données statiques sont stockés à un seul endroit et partagés par tous les objets. La valeur d'un membre de données 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 ont la garantie d'accéder à la même valeur mise à jour, ce qui améliore l'efficacité temporelle.

L'utilisation et les précautions relatives aux membres de données statiques sont les suivantes :

1. Lors de la définition ou de la déclaration d'un membre de données statique, ajoutez le mot-clé static devant.

2. L'initialisation des membres statiques est différente de l'initialisation des membres de données ordinaires. Le format d'initialisation des membres de données statiques est le suivant :

 
<data type><class name>::<static data member name>=<value>

Cela indique :

  • (1) L'initialisation est effectuée en dehors du corps de la classe, et static n'est pas ajouté devant, afin d'éviter toute confusion avec des variables ou des objets statiques ordinaires.
  • (2) Lors de l'initialisation, n'ajoutez pas les spécificateurs de contrôle d'accès du membre tels que private, public, etc.
  • (3) Lors de l'initialisation, utilisez l'opérateur de résolution de portée pour indiquer la classe à laquelle il appartient. Par conséquent, les membres de données statiques sont des membres de la classe, et non des membres d'un objet.

3. Les membres de données statiques sont stockés de manière statique ; ils ont une durée de vie statique et doivent être initialisés.

4. Lorsque vous référencez un membre de données statique, utilisez le format suivant :

<class name>::<static member name>

Si l'autorisation d'accès du membre de données statique le permet (c'est-à-dire s'il s'agit d'un membre public), le membre de données statique peut être référencé dans le programme en utilisant le format ci-dessus.

L'exemple suivant illustre l'application des membres de données statiques :

Exemple

#include … class Myclass{ public: Myclass(int a, int b, int c); void GetNumber(); void GetSum(); private: int A, B, C; static int Sum; }; int Myclass::Sum = 0; Myclass::Myclass(int a, int b, int c){ A = a; B = b; C = c; Sum += A+B+C; } void Myclass::GetNumber(){ cout<<"Number="<<a<<","<<b<<","<<c<<endl; } void Myclass::GetSum(){ cout<<"Sum="<<sum<<endl; } void main(){ Myclass M(3, 7, 10),N(14, 9, 11); M.GetNumber(); N.GetNumber(); M.GetSum(); N.GetSum(); }

À partir de la sortie, on peut voir que la valeur de Sum est égale pour l’objet M et l’objet N. Cela s’explique par le fait que lors de l’initialisation de l’objet M, les valeurs des trois membres de données int de l’objet M sont additionnées et affectées à Sum, donc Sum stocke cette valeur. Lors de l’initialisation de l’objet N, les valeurs des trois membres de données int de l’objet N sont additionnées puis ajoutées à la valeur existante de Sum, donc Sum stockera la nouvelle valeur. Par conséquent, la valeur référencée via l’objet M ou l’objet N est la même, à savoir 54.

Fonction membre statique

Comme les membres de données statiques, les fonctions membres statiques font partie des membres statiques de la classe ; elles ne sont pas des membres d’objet. Par conséquent, référencer des membres statiques ne nécessite pas d’utiliser un nom d’objet.

Dans l’implémentation d’une fonction membre statique, les membres non statiques déclarés dans la classe ne peuvent pas être référencés directement, mais les membres statiques déclarés dans la classe peuvent l’être. Si une fonction membre statique doit référencer des membres non statiques, elle peut le faire par l’intermédiaire d’un objet. L’exemple suivant illustre cela.

Exemple

#include … class M{ public: M(int a){ A=a; B+=a; } static void f1(M m); private: int A; static int B; }; void M::f1(M m) { cout<<"A="<<m.a<<endl; cout<<"B="<<b<<endl; } int M::B=0; void main() { M P(5),Q(10); M::f1(P); //Aucun nom d'objet n'est nécessaire lors de l'appel M::f1(Q); }

Les lecteurs peuvent analyser le résultat par eux-mêmes. On peut voir que l'appel d'une fonction membre statique utilise le format suivant :

  
<class name>::<static member function name>(<parameter list>);

Méthodes d'initialisation pour différents types de variables membres en C++

Les différents types de membres en C++ ont différentes méthodes d'initialisation selon qu'ils sont statiques ou const. La syntaxe de Java n'est pas aussi compliquée ; pas étonnant que tant de personnes se mettent toutes à apprendre Java. Dans le passé, on m'a posé cette question en entretien et je n'ai pas pu y répondre. Quand j'écrivais du code, je me trompais souvent. Ici, j'ai consulté un livre et je l'ai résumé.

//-----------------Test.h---------------------------- #pragma once class Test { private : int var1; // int var11= 4; méthode d'initialisation incorrecte const int var2 ; // const int var22 =22222; méthode d'initialisation incorrecte static int var3; // static int var3333=33333; erreur : seuls les membres static const int peuvent être initialisés par affectation directe static const int var4=4444; // Correct, les membres static const peuvent être initialisés directement static const int var44; public: Test(void); ~Test(void); }; //--------------------Test.cpp----------------------------------- #include ".\test.h" int Test::var3 = 3333333; // Méthode d'initialisation correcte pour les membres statiques // int Test::var1 = 11111;; erreur : seuls les membres statiques peuvent être initialisés // int Test::var2 = 22222; erreur // int Test::var44 = 44444; // méthode incorrecte, donne une erreur de redéfinition Test::Test(void):var1(11111),var2(22222)Méthode d'initialisation correcte//var3(33333) ne peut pas être initialisé ici { var1 =11111; // Correct, les variables ordinaires peuvent également être initialisées ici //var2 = 222222; erreur, car une constante ne peut pas être assignée ; elle ne peut être initialisée que dans le "initialiseur de constructeur (liste d'initialisation du constructeur)" var3 =44444; // Cette affectation est correcte, mais comme tous les objets partagent un même membre statique, cela affectera les autres ; cela peut difficilement être appelé une initialisation } Test::~Test(void){} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Certaines variables membres ont des types de données spéciaux, et leurs méthodes d'initialisation diffèrent également de celles des variables membres de types de données ordinaires. Ces types spéciaux de variables membres incluent :

  • a. Variables membres constantes
  • b. Variables membres de référence
  • c. Variables membres statiques
  • d. Variables membres statiques constantes de type intégral
  • e. Variables membres statiques constantes de type non intégral

Pour les variables membres constantes et les variables membres de référence, l'initialisation doit être effectuée via la liste d'initialisation du constructeur. L'affectation de valeurs aux variables membres constantes et aux variables membres de référence dans le corps du constructeur n'est pas possible.

L'initialisation des variables membres statiques est également assez particulière.

Référez-vous au code suivant et à ses commentaires :

// Initialisation d'un membre de données spécial #include <iostream> using namespace std; class BClass { public: BClass() : i(1),ci(2), ri(i) // Pour les variables membres constantes et les variables membres de référence, l'initialisation doit être effectuée via la liste paramétrée. L'affectation de valeurs dans le corps du constructeur n'est pas possible. { // Variable membre ordinaire } voidprint_values() { cout<< "i =\t" << i << endl; cout<< "ci =\t" << ci << endl; cout<< "ri =\t" << ri << endl; cout<< "si =\t" << si << endl; cout<< "csi =\t" << csi << endl; cout<< "csi2 =\t" << csi2 << endl; cout<< "csd =\t" << csd << endl; } private: inti; // Variable membre constante constint ci; // Variable membre de référence int&ri; // Variable membre statique staticint si; //staticint si2 = 100; // erreur : seules les variables membres constantes statiques peuvent être initialisées de cette façon // Variable membre constante statique staticconst int csi; // Initialisation d'une variable membre constante statique (type intégral) (1) staticconst int csi2 = 100; // Variable membre constante statique (type non intégral) staticconst double csd; //staticconst double csd2 = 99.9; // erreur : seuls les membres de données constants intégraux statiques peuvent être initialisés dans la classe // Initialisation d'une variable membre statique (type intégral) }; // Initialisation d'une variable membre constante statique (type intégral) int BClass::si = 0; // Initialisation d'une variable membre constante statique (type non intégral) const int BClass::csi = 1; // Lors de l'initialisation de csi2 en (1), selon Stanley B. Lippman, la ligne suivante est nécessaire. const double BClass::csd = 99.9; // Cependant, dans VC2003, avoir la ligne suivante provoquera une erreur, tandis que dans VC2005, la ligne suivante est facultative ; cela dépend du compilateur. Résumé des membres statiques C++, C++, static const int BClass::csi2; int main(void) { BClassb_class; b_class.print_values(); return0; }

Résumé des membres statiques C++, C++, static

Ensuite, j'ai réfléchi profondément et j'ai décidé de résumer minutieusement les points clés concernant les membres statiques de classe, afin que lors de futurs entretiens je ne sois pas passif sur de telles questions.

Les membres statiques de classe comprennent deux parties : les membres de données statiques et les membres de fonction statiques.

Membres de données statiques

Membre de données statique

1. Définition des membres de données statiques.

Les membres de données statiques sont en fait des variables globales dans la portée de la classe. Par conséquent, la définition (initialisation) des membres de données statiques ne doit pas être placée dans les fichiers d'en-tête. (Déclaration vs définition (initialisation)) Leur méthode de définition est la même que celle des variables globales. Exemple :

Fichier

xxx.h// Déclaration. Le C++ standard prend en charge l'initialisation des types intégraux dans le corps de la classe, mais VC6 ne le fait pas.class base{ private: static const int _i;File }; xxx.cpp// La définition (initialisation) n'est pas limitée par les restrictions d'accès private et protected.const int base::_i=10;Remarque :

N'essayez pas de définir (initialiser) les membres de données statiques dans les fichiers d'en-tête. Dans la plupart des cas, cela provoquera des erreurs telles qu'une redéfinition. Même si vous ajoutezou#ifndef #define #endifcela ne fonctionnera toujours pas.#pragma once2. Les membres de données statiques sont partagés par tous les objets de la classe, y compris les objets des classes dérivées de cette classe. Autrement dit, les objets de classe dérivée et les objets de classe de base partagent les membres de données statiques de la classe de base. Exemple :

// Déclaration

class base{ public : static int _num;// Définition réelle du membre de données statique }; int base::_num=0;// Le résultat est 1,2 ; on peut voir que la classe dérivée et la classe de base partagent un même membre de données statique. class derived:public base{ }; main() { base a; derived b; a._num++; cout<<"le numéro de données statique de la classe de base _num est"<<a._num<<endl; b._num++; cout<<"le numéro de données statique de la classe dérivée _num est"<<b._num<<endl; } 3. Les membres de données statiques peuvent être utilisés comme arguments par défaut des fonctions membres, tandis que les membres de données ordinaires ne le peuvent pas. Exemple :

// Correct, _staticVar est un membre de données statique

class base{ public : static int _staticVar; int _var; void foo1(int i=_staticVar);// Erreur, _var est un membre de données ordinaire void foo2(int i=_var);4. Le type d'un membre de données statique peut être le type de sa propre classe, tandis qu'un membre de données ordinaire ne le peut pas. Un membre de données ordinaire ne peut être déclaré que comme un pointeur ou une référence au type de sa propre classe. Exemple : };

// Correct, membre de données statique

class base{ public : static base_object1;// Erreur base _object2;// Correct, pointeur base *pObject;// Correct, référence base &mObject;5. Je ne sais pas si cette fonctionnalité appartient au C++ standard ou est une fonctionnalité spécifique à VC6. };

La valeur d'un membre de données statique peut être légalement modifiée dans une fonction membre const. Exemple :

// fonction membre const

class base{ public: base(){ _i=0; _val=0; } mutable int _i; static int _staticVal; int _val; void test() const{// Correct, membre de données mutable _i++;// Correct, membre de données statique _staticVal++;// Erreur _val++;Fonctions membres statiques } }; int base::_staticVal=0;

Fonction membre statique

1. L'adresse d'une fonction membre statique peut être stockée dans un pointeur de fonction ordinaire, tandis que l'adresse d'une fonction membre ordinaire doit être stockée dans un pointeur de fonction membre de classe. Exemple :

// Pointeur de fonction ordinaire

class base{ static int func1(); int func2(); }; int (*pf1)()=&base::func1;// Pointeur de fonction membre int (base::*pf2)()=&base::func2;2. Les fonctions membres statiques ne peuvent pas appeler des membres non statiques de la classe, car les fonctions membres statiques ne contiennent pas de pointeur this.

3. Les fonctions membres statiques ne peuvent pas être déclarées en même temps comme des fonctions virtual, const ou volatile. Exemple :

// Erreur

class base{ virtual static void func1();// Erreur static void func2() const;// Erreur static void func3() volatile;Le dernier point à mentionner est que les membres statiques sont accessibles indépendamment, c'est-à-dire qu'on peut y accéder sans créer d'instance d'objet. };

Auteur : SDMrFeng

Original : https://blog.csdn.net/tobefxz/article/details/14109697

Pycharm Importer des packages, modules Python