Le mot-clé static
est un mot qui a plusieurs significations en C ++ et que je trouve très déroutant et je ne peux jamais me pencher sur son fonctionnement réel.
D’après ce que j’ai compris, il y a static
durée de stockage static
, ce qui signifie qu’elle dure toute la vie du programme dans le cas d’un global, mais lorsque vous parlez d’un local, cela signifie qu’il est initialisé par défaut.
Le standard C ++ le dit pour les membres de données de classe avec le mot-clé static
:
3.7.1 Durée de stockage statique [basic.stc.static]
3 Le mot-clé static peut être utilisé pour déclarer une variable locale avec une durée de stockage statique.
4 Le mot clé static appliqué à un membre de données de classe dans une définition de classe donne à la durée de stockage statique de la donnée membre.
Qu’est-ce que cela signifie avec la variable locale ? Est-ce une variable locale de fonction? Parce qu’il y a aussi cela quand vous déclarez une fonction locale comme static
qu’elle n’est initialisée qu’une fois, la première fois qu’elle entre dans cette fonction.
Il ne parle également que de la durée de stockage en ce qui concerne les membres de la classe, qu’en est-il de la non-spécificité des instances, qui est également une propriété de la static
non? Ou est-ce la durée de stockage?
Maintenant, qu’en est-il du cas avec static
et la scope du fichier? Toutes les variables globales sont-elles considérées comme ayant une durée de stockage statique par défaut? Ce qui suit (de la section 3.7.1) semble l’indiquer:
1 Toutes les variables qui n’ont pas de durée de stockage dynamic, n’ont pas de durée de stockage de threads et ne sont pas locales, ont une durée de stockage statique. Le stockage pour ces entités doit durer pendant toute la durée du programme (3.6.2, 3.6.3)
Comment la static
rapporte-t-elle à la liaison d’une variable?
Tout ce mot-clé static
est complètement déroutant, est-ce que quelqu’un peut clarifier les différentes utilisations de l’anglais et me dire quand initialiser un membre de classe static
?
static
variables static
existent pour la “durée de vie” de l’ unité de traduction dans laquelle il est défini , et:
static
, mais peuvent être adressés à partir de la classe aussi bien que d’une instance (comme std::ssortingng::npos
). [Remarque: vous pouvez déclarer des membres statiques dans une classe, mais ils doivent toujours être définis dans une unité de traduction (fichier cpp), et en tant que tel, il n’y en a qu’un par classe] emplacements en tant que code:
static std::ssortingng namespaceScope = "Hello"; void foo() { static std::ssortingng functionScope= "World"; } struct A { static std::ssortingng classScope = "!"; };
Avant qu’une fonction dans une unité de traduction ne soit exécutée (éventuellement après l’exécution main
), les variables avec une durée de stockage statique (étendue d’espace de nommage) dans cette unité de traduction seront “initialisées en permanence” ( constexpr
si possible, ou zéro sinon), puis les non-locaux sont “initialisés dynamicment” correctement dans l’ordre de leur définition dans l’unité de traduction (pour des choses comme std::ssortingng="HI";
qui ne sont pas constexpr
). Enfin, la statique locale de la fonction sera initialisée à la première exécution “atteindra” la ligne où elles sont déclarées. Toutes static
variables static
toutes détruites dans l’ordre inverse de l’initialisation.
La manière la plus simple d’obtenir tout ce droit est de faire en sorte que toutes les variables statiques qui ne sont pas constexpr
initialisées dans les locals statiques de la fonction, ce qui garantit que toutes vos statiques / globales sont correctement initialisées. fiasco d’ordre d’initialisation .
T& get_global() { static T global = initial_value(); return global; }
Attention, lorsque la spécification indique que les variables d’espace de nommage ont une «durée de stockage statique» par défaut, elles signifient le bit «durée de vie de l’unité de traduction», mais cela ne signifie pas qu’elle n’est pas accessible en dehors du fichier.
Plus simple, le static
est souvent utilisé comme une fonction membre de classe et très rarement utilisé pour une fonction autonome.
Une fonction membre statique diffère d’une fonction membre classique en ce sens qu’elle peut être appelée sans instance d’une classe et, comme elle n’a pas d’instance, elle ne peut pas accéder aux membres non statiques de la classe. Les variables statiques sont utiles lorsque vous souhaitez avoir une fonction pour une classe qui ne fait absolument pas référence à des membres d’instance ou pour gérer static
variables de membre static
.
struct A { A() {++A_count;} A(const A&) {++A_count;} A(A&&) {++A_count;} ~A() {--A_count;} static int get_count() {return A_count;} private: static int A_count; } int main() { A var; int c0 = var.get_count(); //some comstackrs give a warning, but it's ok. int c1 = A::get_count(); //normal way }
Une fonction libre static
signifie que la fonction ne sera désignée par aucune autre unité de traduction et que l’éditeur de liens peut donc l’ignorer complètement. Cela a un petit nombre de fins:
static void log(const char*) {}
dans chaque fichier cpp et chacun peut se connecter différemment. La durée de stockage statique signifie que la variable réside au même endroit en mémoire pendant toute la durée de vie du programme.
La liaison est orthogonale à ceci.
Je pense que c’est la distinction la plus importante que vous puissiez faire. Comprenez cela et le rest, tout en vous en souvenant, devrait être facile (ne pas aborder directement @Tony, mais quiconque pourrait le lire à l’avenir).
Le mot-clé static
peut être utilisé pour indiquer la liaison interne et le stockage statique, mais ceux-ci sont essentiellement différents.
Qu’est-ce que cela signifie avec la variable locale? Est-ce une variable locale de fonction?
Oui. Indépendamment du moment où la variable est initialisée (lors du premier appel à la fonction et lorsque le chemin d’exécution atteint le sharepoint déclaration), elle se trouvera au même endroit en mémoire pour la durée de vie du programme. Dans ce cas, le static
lui donne un stockage statique.
Maintenant, qu’en est-il du cas avec statique et la scope du fichier? Toutes les variables globales sont-elles considérées comme ayant une durée de stockage statique par défaut?
Oui, tous les globals ont par définition une durée de stockage statique (maintenant que nous avons effacé ce que cela signifie). Mais les variables de scope d’espace de noms ne sont pas déclarées static
, car cela leur donnerait un lien interne, donc une variable par unité de traduction.
Comment la statique se rapporte-t-elle à la liaison d’une variable?
Il donne des variables internes aux variables d’espace de noms. Il donne aux membres et aux variables locales une durée de stockage statique.
Développons tout cela:
// static int x; //internal linkage //non-static storage - each translation unit will have its own copy of x //NOT A TRUE GLOBAL! int y; //static storage duration (can be used with extern) //actual global //external linkage struct X { static int x; //static storage duration - shared between classes }; void foo() { static int x; //static storage duration - shared between calls }
Tout ce mot-clé statique est complètement déroutant
Certainement, à moins que vous ne le connaissiez. 🙂 En essayant d’éviter d’append de nouveaux mots-clés à la langue, le comité a réutilisé celui-ci, l’OMI, à cet effet – de la confusion. Il est utilisé pour signifier différentes choses (pourrais-je dire, probablement des choses opposées).
C’est en fait assez simple. Si vous déclarez une variable comme statique dans le cadre d’une fonction, sa valeur est préservée entre les appels successifs à cette fonction. Alors:
int myFun() { static int i=5; i++; return i; } int main() { printf("%d", myFun()); printf("%d", myFun()); printf("%d", myFun()); }
affichera 678
au lieu de 666
, car il se souvient de la valeur incrémentée.
En ce qui concerne les membres statiques, ils conservent leur valeur à travers les instances de la classe. Donc le code suivant:
struct A { static int a; }; int main() { A first; A second; first.a = 3; second.a = 4; printf("%d", first.a); }
imprimera 4, car first.a et second.a sont essentiellement la même variable. En ce qui concerne l’initialisation, voir cette question.
Afin de clarifier la question, je préfère classer l’utilisation du mot clé «statique» sous trois formes différentes:
(UNE). les variables
(B). les fonctions
(C). variables membres / fonctions de classes
l’explication suit ci-dessous pour chacun des sous-titres:
(A) mot clé ‘statique’ pour les variables
Celui-ci peut être un peu compliqué, mais s’il est expliqué et compris correctement, c’est assez simple.
Pour expliquer cela, il est d’abord utile de connaître la scope, la durée et le lien des variables, sans lesquelles il est toujours difficile de voir à travers le concept obscur du mot-clé staic.
1. Portée : détermine où dans le fichier, la variable est accessible. Il peut être de deux types: (i) Local ou Block Scope . ii) scope mondiale
2. Durée : détermine quand une variable est créée et détruite. Là encore, il existe deux types: (i) Durée de stockage automatique (pour les variables ayant une scope locale ou bloc). (ii) Durée de stockage statique (pour les variables ayant une scope globale ou des variables locales (dans une fonction ou dans un bloc de code) avec un spécificateur statique ).
3. Liaison : détermine si une variable peut être accessible (ou liée) dans un autre fichier. Encore une fois (et heureusement), il existe deux types: (i) Liaison interne (pour les variables ayant une scope de bloc et une scope / scope de fichier globales / espace de noms global) (ii) Liaison externe (pour les variables ne Étendue de l’espace de noms global)
Reportons un exemple ci-dessous pour une meilleure compréhension des variables globales et locales simples (pas de variables locales avec une durée de stockage statique):
//main file #include int global_var1; //has global scope const global_var2(1.618); //has global scope int main() { //these variables are local to the block main. //they have automatic duration, ie, they are created when the main() is // executed and destroyed, when main goes out of scope int local_var1(23); const double local_var2(3.14); { /* this is yet another block, all variables declared within this block are have local scope limited within this block. */ // all variables declared within this block too have automatic duration, ie, /*they are created at the point of definition within this block, and destroyed as soon as this block ends */ char block_char1; int local_var1(32) //NOTE: this has been re-declared within the block, //it shadows the local_var1 declared outside std::cout << local_var1 <<"\n"; //prints 32 }//end of block //local_var1 declared inside goes out of scope std::cout << local_var1 << "\n"; //prints 23 global_var1 = 29; //global_var1 has been declared outside main (global scope) std::cout << global_var1 << "\n"; //prints 29 std::cout << global_var2 << "\n"; //prints 1.618 return 0; } //local_var1, local_var2 go out of scope as main ends //global_var1, global_var2 go out of scope as the program terminates //(in this case program ends with end of main, so both local and global //variable go out of scope together
Maintenant vient le concept de liaison. Lorsqu'une variable globale définie dans un fichier est destinée à être utilisée dans un autre fichier, la liaison de la variable joue un rôle important.
La liaison des variables globales est spécifiée par les mots-clés suivants: (i) statique et (ii) externe
(Maintenant vous obtenez l'explication ;-))
Le mot-clé statique peut être appliqué à des variables ayant une scope locale et globale, et dans les deux cas, elles signifient différentes choses. Je vais d'abord expliquer l'utilisation du mot-clé 'static' dans les variables ayant une scope globale (où je clarifie également l'utilisation du mot-clé 'extern') et plus tard pour celles ayant une scope locale.
1. Mot-clé statique pour les variables ayant une scope globale
Les variables globales ont une durée statique, ce qui signifie qu'elles ne sortent pas de la scope lorsqu'un bloc de code particulier (par exemple main ()) dans lequel il est utilisé se termine. Selon la liaison, ils ne peuvent être accédés que dans le même fichier où ils sont déclarés (pour la variable globale statique), ou en dehors du fichier même en dehors du fichier dans lequel ils sont déclarés (variables globales de type externe).
Dans le cas d'une variable globale ayant un spécificateur externe, et si cette variable est accessible en dehors du fichier dans lequel elle a été initialisée, elle doit être déclarée dans le fichier où elle est utilisée, comme une fonction doit être transmise. déclaré si sa définition est dans un fichier différent de celui où il est utilisé.
En revanche, si la variable globale a un mot-clé statique, elle ne peut pas être utilisée dans un fichier en dehors duquel elle a été déclarée.
(voir exemple ci-dessous pour clarification)
par exemple:
//main2.cpp static int global_var3 = 23; /*static global variable, cannot be accessed in anyother file */ extern double global_var4 = 71; /*can be accessed outside this file linked to main2.cpp */ int main() { return 0; }
main3.cpp
//main3.cpp #include int main() { extern int gloabl_var4; /*this variable refers to the gloabal_var4 defined in the main2.cpp file */ std::cout << global_var4 << "\n"; //prints 71; return 0; }
maintenant, toute variable de c ++ peut être soit un const, soit un non-const et pour chaque «const-ness», nous obtenons deux cas de linkage c ++ par défaut, si aucun n'est spécifié:
(i) Si une variable globale est non-const, sa liaison est externe par défaut , c.-à-d. que la variable globale non-const est accessible dans un autre fichier .cpp par déclaration à l'aide du mot-clé extern les variables ont un lien externe (avec une durée statique bien sûr)). L'utilisation du mot-clé extern dans le fichier d'origine où il a été défini est également redondante. Dans ce cas, pour rendre une variable globale non-const inaccessible au fichier externe, utilisez le spécificateur 'static' avant le type de la variable .
(ii) Si une variable globale est const, sa liaison est statique par défaut , c’est-à-dire qu’une variable constante const n’est pas accessible dans un fichier autre que celui où elle est définie bien sûr)). L'utilisation de mot-clé statique pour empêcher l'access à une variable globale const dans un autre fichier est également inutile. Ici, pour qu'une variable globale const ait un lien externe, utilisez le spécificateur 'extern' avant le type de la variable
Voici un résumé pour les variables de scope globale avec différents liens
//globalVariables1.cpp // defining uninitialized vairbles int globalVar1; // uninitialized global variable with external linkage static int globalVar2; // uninitialized global variable with internal linkage const int globalVar3; // error, since const variables must be initialized upon declaration const int globalVar4 = 23; //correct, but with static linkage (cannot be accessed outside the file where it has been declared*/ extern const double globalVar5 = 1.57; //this const variable ca be accessed outside the file where it has been declared
Ensuite, nous étudions comment les variables globales ci-dessus se comportent lorsqu'elles sont accédées dans un fichier différent.
//using_globalVariables1.cpp (eg for the usage of global variables above) // Forward declaration via extern keyword: extern int globalVar1; // correct since globalVar1 is not a const or static extern int globalVar2; //incorrect since globalVar2 has internal linkage extern const int globalVar4; /* incorrect since globalVar4 has no extern specifier, limited to internal linkage by default (static specifier for const variables) */ extern const double globalVar5; /*correct since in the previous file, it has extern specifier, no need to initialize the const variable here, since it has already been legitimately defined perviously */
2. Mot-clé statique pour les variables avec scope locale
Auparavant, j'ai mentionné que les variables avec une scope locale ont une durée automatique, c’est-à-dire qu’elles existent au moment où le bloc est entré (que ce soit un bloc fonctionnel) et cessent d’exister à la fin du bloc. avec la scope locale, la durée automatique et les variables de durée automatique (et les objects) n'ont pas de lien, ce qui signifie qu'elles ne sont pas visibles en dehors du bloc de code.
Si le spécificateur statique est appliqué à une variable locale dans un bloc, la durée de la variable passe de automatique à statique et sa durée de vie correspond à la durée totale du programme, ce qui signifie qu’elle a un emplacement de mémoire fixe. avant le démarrage du programme comme mentionné dans la référence cpp (l'initialisation ne doit pas être confondue avec l'affectation)
Regardons un exemple.
//localVarDemo.cpp #include int localNextID() { int tempID = 1; //tempID created here return tempID++; //copy of tempID returned and tempID incremented to 2 } //tempID destroyed here, hence value of tempID lost int newNextID() { static int newID = 0;//newID has static duration, with internal linkage return newID++; //copy of newID returned and newID incremented by 1 } //newID doesn't get destroyed here :-) int main() { int employeeID1 = nextID(); //employeeID1 = 1 int employeeID2 = nextID(); // employeeID2 = 1 again (not desired) int employeeID3 = newNextID(); //employeeID3 = 0; int employeeID4 = newNextID(); //employeeID4 = 1; int employeeID5 = newNextID(); //employeeID5 = 2; return 0; }
ceci conclut mon explication du mot-clé statique appliqué aux variables. Pheww !!!
B. Mot-clé 'statique' utilisé pour les fonctions
en termes de fonctions, le mot-clé statique a un sens simple. Ici, il fait référence à la liaison de la fonction. Normalement, toutes les fonctions déclarées dans un fichier cpp ont un lien externe par défaut, c.-à-d. Une fonction définie dans un fichier peut être utilisée dans une autre déclaration cpp.
L'utilisation d'un mot-clé statique avant la déclaration de fonction limite sa liaison à interne , c'est-à-dire qu'une fonction statique ne peut pas être utilisée dans un fichier en dehors de sa définition.
C. Staitc Mot-clé utilisé pour les variables membres et les fonctions des classes
1. Mot clé 'statique' pour les variables membres des classes
Je commence directement avec un exemple ici
#include class DesignNumber { private: static int m_designNum; //design number int m_iteration; // number of iterations performed for the design public: DesignNumber() { } //default constructor int getItrNum() //get the iteration number of design { m_iteration = m_designNum++; return m_iteration; } static int m_anyVariable; //public static variable }; int DesignNumber::m_designNum = 0; // starting with design id = 0 // note : no need of static keyword here //causes comstackr error if static keyword used int DesignNumber::m_anyNumber = 99; /* initialization of inclass public static member */ enter code here int main() { DesignNumber firstDesign, secondDesign, thirdDesign; std::cout << firstDesign.getItrNum() << "\n"; //prints 0 std::cout << secondDesign.getItrNum() << "\n"; //prints 1 std::cout << thirdDesign.getItrNum() << "\n"; //prints 2 std::cout << DesignNumber::m_anyNumber++ << "\n"; /* no object associated with m_anyNumber */ std::cout << DesignNumber::m_anyNumber++ << "\n"; //prints 100 std::cout << DesignNumber::m_anyNumber++ << "\n"; //prints 101 return 0; }
Dans cet exemple, la variable statique m_designNum conserve sa valeur et cette seule variable de membre privé (car elle est statique) est partagée avec toutes les variables du type d'object DesignNumber
Comme les autres variables membres, les variables membres statiques d'une classe ne sont associées à aucun object de classe, ce qui est démontré par l'impression de anyNumber dans la fonction principale.
variables de membre const vs non-const en classe
(i) variables de membre statiques de classe non const Dans l'exemple précédent, les membres statiques (publics et privés) n'étaient pas des constantes. La norme ISO interdit l'initialisation des membres statiques non constants dans la classe. Par conséquent, comme dans l'exemple précédent, ils doivent être initalisés après la définition de la classe, sous réserve que le mot-clé statique doive être omis.
(ii) les variables membres const-static de la classe sont simples et vont de pair avec la convention d’initialisation des autres variables const, c’est-à-dire que les variables const des membres d’une classe peuvent être initialisées à la fin de la déclaration. de la déclaration de classe avec une mise en garde que le mot-clé const doit être ajouté au membre statique lorsqu’il est initialisé après la définition de classe.
Je recommande toutefois d'initialiser les variables de membre const statiques au sharepoint déclaration. Cela va avec la convention C ++ standard et rend le code plus propre
Pour plus d'exemples sur les variables membres statiques dans une classe, consultez le lien suivant à partir de learncpp.com http://www.learncpp.com/cpp-tutorial/811-static-member-variables/
2. mot clé 'statique' pour la fonction membre des classes
Tout comme les variables membres des classes peuvent être statiques, les fonctions membres des classes le peuvent aussi. Les fonctions membres normales des classes sont toujours associées à un object du type de classe. En revanche, les fonctions membres statiques d'une classe ne sont associées à aucun object de la classe, c'est-à-dire qu'elles n'ont pas ce pointeur.
Deuxièmement, comme les fonctions membres statiques de la classe n'ont pas ce pointeur, elles peuvent être appelées en utilisant le nom de classe et l'opérateur de résolution de scope dans la fonction principale (ClassName :: functionName ();)
Troisièmement, les fonctions membres statiques d'une classe peuvent uniquement accéder aux variables membres statiques d'une classe, étant donné que les variables membres non statiques d'une classe doivent appartenir à un object de classe.
Pour plus d'exemples sur les fonctions de membre statiques dans une classe, consultez le lien suivant à partir de learncpp.com
http://www.learncpp.com/cpp-tutorial/812-static-member-functions/
Les variables statiques sont partagées entre chaque instance d’une classe, au lieu que chaque classe ait sa propre variable.
class MyClass { public: int myVar; static int myStaticVar; }; //Static member variables must be initialized. Unless you're using C++11, or it's an integer type, //they have to be defined and initialized outside of the class like this: MyClass::myStaticVar = 0; MyClass classA; MyClass classB;
Chaque instance de «MyClass» a son propre «myVar», mais partage le même «myStaticVar». En fait, vous n’avez même pas besoin d’une instance de MyClass pour accéder à «myStaticVar», et vous pouvez y accéder en dehors de la classe comme ceci:
MyClass::myStaticVar //Assuming it's publicly accessible.
Lorsqu’il est utilisé dans une fonction en tant que variable locale (et non en tant que variable membre de classe), le mot clé statique fait quelque chose de différent. Il vous permet de créer une variable persistante sans donner de scope globale.
int myFunc() { int myVar = 0; //Each time the code reaches here, a new variable called 'myVar' is initialized. myVar++; //Given the above code, this will *always* print '1'. std::cout << myVar << std::endl; //The first time the code reaches here, 'myStaticVar' is initialized. But ONLY the first time. static int myStaticVar = 0; //Each time the code reaches here, myStaticVar is incremented. myStaticVar++; //This will print a continuously incrementing number, //each time the function is called. '1', '2', '3', etc... std::cout << myStaticVar << std::endl; }
C'est une variable globale en termes de persistance ... mais sans être globale en termes de scope / d'accessibilité.
Vous pouvez également avoir des fonctions membres statiques. Les fonctions statiques sont essentiellement des fonctions non membres, mais à l'intérieur de l'espace de noms du nom de la classe et avec un access privé aux membres de la classe.
class MyClass { public: int Func() { //...do something... } static int StaticFunc() { //...do something... } }; int main() { MyClass myClassA; myClassA.Func(); //Calls 'Func'. myClassA.StaticFunc(); //Calls 'StaticFunc'. MyClass::StaticFunc(); //Calls 'StaticFunc'. MyClass::Func(); //Error: You can't call a non-static member-function without a class instance! return 0; }
Lorsque vous appelez une fonction membre, il existe un paramètre caché appelé 'this', qui est un pointeur sur l'instance de la classe appelant la fonction. Les fonctions membres statiques n'ont pas ce paramètre caché ... elles sont appelables sans instance de classe, mais elles ne peuvent pas non plus accéder aux variables membres non statiques d'une classe, car elles ne disposent pas d'un pointeur 'this'. Ils ne sont appelés sur aucune instance de classe spécifique.
Lorsque vous déclarez une variable static
au niveau du fichier, cette variable est uniquement disponible dans ce fichier particulier (techniquement, l’unité de traduction *, mais ne compliquons pas trop cela). Par exemple:
a.cpp
static int x = 7; void printax() { cout << "from a.cpp: x=" << x << endl; }
b.cpp
static int x = 9; void printbx() { cout << "from b.cpp: x=" << x << endl; }
main.cpp:
int main(int, char **) { printax(); // Will print 7 printbx(); // Will print 9 return 0; }
Pour une variable locale , static
signifie que la variable sera initialisée à zéro et conservera sa valeur entre les appels:
unsigned int powersoftwo() { static unsigned lastpow; if(lastpow == 0) lastpow = 1; else lastpow *= 2; return lastpow; } int main(int, char **) { for(int i = 0; i != 10; i++) cout << "2^" << i << " = " << powersoftwo() << endl; }
Pour les variables de classe , cela signifie qu'il n'y a qu'une seule instance de cette variable qui est partagée par tous les membres de cette classe. Selon les permissions, la variable est accessible depuis l'extérieur de la classe en utilisant son nom complet.
class Test { private: static char *xxx; public: static int yyy; public: Test() { cout << this << "The static class variable xxx is at address " << static_cast(xxx) << endl; cout << this << "The static class variable yyy is at address " << static_cast (&y) << endl; } }; // Necessary for static class variables. char *Test::xxx = "I'm Triple X!"; int Test::yyy = 0; int main(int, char **) { Test t1; Test t2; Test::yyy = 666; Test t3; };
Marquer une fonction non-class comme static
rend la fonction uniquement accessible à partir de ce fichier et inaccessible à partir d'autres fichiers.
a.cpp
static void printfilename() { // this is the printfilename from a.cpp - // it can't be accessed from any other file cout << "this is a.cpp" << endl; }
b.cpp
static void printfilename() { // this is the printfilename from b.cpp - // it can't be accessed from any other file cout << "this is b.cpp" << endl; }
Pour les fonctions de membre de classe, les marquer comme static
signifie qu'il n'est pas nécessaire d'appeler la fonction sur une instance particulière d'un object (c'est-à-dire qu'elle n'a pas this
pointeur).
class Test { private: static int count; public: static int GetTestCount() { return count; }; Test() { cout << this << "Created an instance of Test" << endl; count++; } ~Test() { cout << this << "Destroyed an instance of Test" << endl; count--; } }; int Test::count = 0; int main(int, char **) { Test *arr[10] = { NULL }; for(int i = 0; i != 10; i++) arr[i] = new Test(); cout << "There are " << Test::GetTestCount() << " instances of the Test class!" << endl; // now, delete them all except the first and last! for(int i = 1; i != 9; i++) delete arr[i]; cout << "There are " << Test::GetTestCount() << " instances of the Test class!" << endl; delete arr[0]; cout << "There are " << Test::GetTestCount() << " instances of the Test class!" << endl; delete arr[9]; cout << "There are " << Test::GetTestCount() << " instances of the Test class!" << endl; return 0; }
Je ne suis pas un programmeur en C alors je ne peux pas vous donner d’informations sur les utilisations de statique dans un programme C, mais quand il s’agit de programmation orientée object, elle déclare essentiellement une variable, une fonction ou une classe. tout au long de la vie du programme. Prends pour exemple.
class A { public: A(); ~A(); void somePublicMethod(); private: void somePrivateMethod(); };
Lorsque vous instanciez cette classe dans votre main, vous faites quelque chose comme ça.
int main() { A a1; //do something on a1 A a2; //do something on a2 }
Ces deux instances de classe sont complètement différentes les unes des autres et fonctionnent indépendamment les unes des autres. Mais si vous deviez recréer la classe A comme ça.
class A { public: A(); ~A(); void somePublicMethod(); static int x; private: void somePrivateMethod(); };
Revenons à nouveau au principal.
int main() { A a1; a1.x = 1; //do something on a1 A a2; a2.x++; //do something on a2 }
Alors a1 et a2 partageraient la même copie de int x si toutes les opérations sur x dans a1 influenceraient directement les opérations de x dans a2. Donc, si je devais le faire
int main() { A a1; a1.x = 1; //do something on a1 cout << a1.x << endl; //this would be 1 A a2; a2.x++; cout << a2.x << endl; //this would be 2 //do something on a2 }
Les deux instances de la classe A partagent des variables et des fonctions statiques. J'espère que ça répond à ta question. Ma connaissance limitée de C me permet de dire que définir une fonction ou une variable comme statique signifie qu’il n’est visible au fichier que si la fonction ou la variable est définie comme statique. C ++ permet à la fois à C et C ++ de déclarer vos variables statiques car leur compatibilité avec C.
Qu’est-ce que cela signifie avec la variable locale? Est-ce une variable locale de fonction?
Oui – Non globale, telle qu’une variable locale de fonction.
Because there’s also that when you declare a function local as static that it is only initialized once, the first time it enters this function.
Droite.
It also only talks about storage duration with regards to class members, what about it being non instance specific, that’s also a property of static no? Or is that storage duration?
class R { static int a; }; // << static lives for the duration of the program
that is to say, all instances of R
share int R::a
-- int R::a
is never copied.
Now what about the case with static and file scope?
Effectively a global which has constructor/destructor where appropriate -- initialization is not deferred until access.
How does static relate to the linkage of a variable?
For a function local, it is external. Access: It's accessible to the function (unless of course, you return it).
For a class, it is external. Access: Standard access specifiers apply (public, protected, private).
static
can also specify internal linkage, depending on where it's declared (file/namespace).
This whole static keyword is downright confusing
It has too many purposes in C++.
can someone clarify the different uses for it English and also tell me when to initialize a static class member?
It's automatically initialized before main
if it's loaded and has a constructor. That might sound like a good thing, but initialization order is largely beyond your control, so complex initialization becomes very difficult to maintain, and you want to minimize this -- if you must have a static, then function local scales much better across libraries and projects. As far as data with static storage duration, you should try to minimize this design, particularly if mutable (global variables). Initialization 'time' also varies for a number of reasons -- the loader and kernel have some sortingcks to minimize memory footprints and defer initialization, depending on the data in question.
Static Object: We can define class members static using static keyword. When we declare a member of a class as static it means no matter how many objects of the class are created, there is only one copy of the static member.
A static member is shared by all objects of the class. All static data is initialized to zero when the first object is created, if no other initialization is present. We can’t put it in the class definition but it can be initialized outside the class as done in the following example by redeclaring the static variable, using the scope resolution operator :: to identify which class it belongs to.
Let us try the following example to understand the concept of static data members:
#include using namespace std; class Box { public: static int objectCount; // Constructor definition Box(double l=2.0, double b=2.0, double h=2.0) { cout <<"Constructor called." << endl; length = l; breadth = b; height = h; // Increase every time object is created objectCount++; } double Volume() { return length * breadth * height; } private: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box }; // Initialize static member of class Box int Box::objectCount = 0; int main(void) { Box Box1(3.3, 1.2, 1.5); // Declare box1 Box Box2(8.5, 6.0, 2.0); // Declare box2 // Print total number of objects. cout << "Total objects: " << Box::objectCount << endl; return 0; }
When the above code is comstackd and executed, it produces the following result:
Constructor called. Constructor called. Total objects: 2
Static Function Members: By declaring a function member as static, you make it independent of any particular object of the class. A static member function can be called even if no objects of the class exist and the static functions are accessed using only the class name and the scope resolution operator ::.
A static member function can only access static data member, other static member functions and any other functions from outside the class.
Static member functions have a class scope and they do not have access to the this pointer of the class. You could use a static member function to determine whether some objects of the class have been created or not.
Let us try the following example to understand the concept of static function members:
#include using namespace std; class Box { public: static int objectCount; // Constructor definition Box(double l=2.0, double b=2.0, double h=2.0) { cout <<"Constructor called." << endl; length = l; breadth = b; height = h; // Increase every time object is created objectCount++; } double Volume() { return length * breadth * height; } static int getCount() { return objectCount; } private: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box }; // Initialize static member of class Box int Box::objectCount = 0; int main(void) { // Print total number of objects before creating object. cout << "Inital Stage Count: " << Box::getCount() << endl; Box Box1(3.3, 1.2, 1.5); // Declare box1 Box Box2(8.5, 6.0, 2.0); // Declare box2 // Print total number of objects after creating object. cout << "Final Stage Count: " << Box::getCount() << endl; return 0; }
When the above code is comstackd and executed, it produces the following result:
Inital Stage Count: 0 Constructor called. Constructor called. Final Stage Count: 2