C++

Durée de vie des objets et durée de stockage en C++

Durée de vie des objets et durée de stockage en C++
Lors de la création d'un objet, son emplacement en mémoire doit être établi, avant qu'il ne soit initialisé. L'initialisation signifie mettre de la valeur dans l'emplacement. La durée de vie d'un objet commence juste après l'initialisation. Lorsqu'un objet meurt, son emplacement (stockage), que l'objet occupait est libéré, puis l'ordinateur est arrêté ou le stockage est occupé (utilisé) par un autre objet. Libérer un moyen de stockage, rendre invalide l'identifiant ou le pointeur qui occupait le stockage. La durée de vie d'un objet se termine, lorsque son stockage est libéré.

Un certain temps est nécessaire pour créer un objet. Il faut du temps pour tuer un objet. Lorsqu'on parle d'un objet, deux choses entrent en jeu : l'emplacement qui est le stockage, et la valeur. La signification de la durée de vie et de la durée de stockage est similaire ; mais la durée se voit plus du point de vue du lieu que du point de vue de la valeur. La durée de stockage est le temps entre le moment où un emplacement est associé à un objet jusqu'au moment où l'emplacement est dissocié de l'objet.

La suite de cet article illustre la durée de vie de l'objet, et explique brièvement les différentes durées de stockage. Vous devez avoir des connaissances de base en C++ pour comprendre cet article. Vous devez également avoir des connaissances dans le domaine C++.

Contenu de l'article

Illustration de la durée de vie de l'objet

Considérez le programme suivant :

#inclure
en utilisant l'espace de noms std ;
int main()

si (1 == 1)

entier x;
x = 1 ;
char y;
y = 'A';
cout << x << y << '\n';

renvoie 0 ;

La sortie est, 1A .

La vie d'un objet touche à sa fin, lorsqu'il sort du cadre. La durée de vie de l'objet x, commence à « x = 1 ; » et se termine à la fin de la if-local-scope. La durée de vie de l'objet y commence à « y = 'A' ; » et se termine à la fin de la if-local-scope. Avant que les deux objets ne meurent, ils sont employés dans l'instruction cout .

Durée de stockage

La durée de stockage est déterminée par l'un des schémas suivants : durée de stockage automatique ; durée de stockage dynamique ; durée de stockage statique ; durée de stockage des threads. Catégories de durée de stockage, s'appliquent également aux références.

Durée de stockage automatique

Si une variable n'est pas déclarée explicitement comme static, thread_local ou extern, alors cette variable a une durée de stockage automatique. Les exemples sont x et y ci-dessus. La durée de ces variables se termine lorsqu'elles sortent du champ d'application. Le programme suivant illustre la durée de stockage automatique d'une référence et d'un pointeur, dans la portée globale.

#inclure
en utilisant l'espace de noms std ;
entier x = 1 ;
entier& m = x;
car y = 'A';
car* n = &y;
int main()

cout << m << *n << '\n';
renvoie 0 ;

La sortie est, 1A .

La durée de m commence à partir de "int& m = x;" et se termine à la fin du programme. La durée de n commence à partir de « char* n = &y ; » et se termine à la fin du programme.

Durée de stockage dynamique

Boutique gratuite

Dans un ordinateur moderne, plusieurs programmes peuvent être exécutés en même temps. Chaque programme a sa propre portion de mémoire. Le reste de la mémoire qui n'est utilisé par aucun programme est appelé magasin libre. L'expression suivante est utilisée pour renvoyer un emplacement pour un entier du magasin gratuit

nouvel international

Cet emplacement (stockage) de l'entier renvoyé doit encore être identifié par affectation à un pointeur. Le code suivant illustre comment utiliser le pointeur avec le magasin gratuit :

int *ptrInt = nouvel entier ;
*ptrInt = 12 ;
cout<< *ptrInt <<'\n';

La sortie est de 12 .

Pour mettre fin à la vie de l'objet, utilisez l'expression delete comme suit :

supprimer ptrInt ;

L'argument de l'expression de suppression est un pointeur. Le code suivant illustre son utilisation :

int *ptrInt = nouvel entier ;
*ptrInt = 12 ;
supprimer ptrInt ;

Un pointeur créé avec la nouvelle expression et supprimé avec l'expression delete, a une durée de stockage dynamique. Ce pointeur meurt lorsqu'il sort de la portée ou est supprimé. La durée de l'objet dans le code précédent, commence à « *ptrInt = 12 ; » et se termine à la fin de la région déclarative (portée). Il y a plus dans les expressions new et delete que ce qui a été discuté ici - voir plus tard.

Durée de stockage statique

Objet statique

Un objet déclaré statique, se comporte comme l'objet ordinaire, sauf que sa durée de stockage, commence à partir de son initialisation jusqu'à la fin du programme. Il ne peut pas être vu en dehors de son champ d'application, mais il peut être indirectement utilisé en dehors de son champ d'application.

Considérons le programme suivant, qui est censé compter de 1 à 5 (ne pas tester le programme) :

#inclure
en utilisant l'espace de noms std ;
entier fn()

int stc = 1;
cout << " << stc;
stc = stc + 1;
si (stc > 5)
renvoie 0 ;
fn();

int main()

fn();
renvoie 0 ;

La sortie est 1 1 1 1 1 1 1 1… et ne finit jamais vraiment. La définition de fonction est une fonction récurrente ; ce qui signifie qu'il continue de s'appeler jusqu'à ce qu'une condition soit remplie.

La solution est de rendre l'objet stc statique. Une fois qu'un objet statique a été initialisé, sa valeur ne peut pas être modifiée, jusqu'à ce que le programme se termine. Le programme suivant (que vous pouvez tester), qui est le même que le précédent, mais maintenant avec stc rendu statique, compte de 1 à 5 :

#inclure
en utilisant l'espace de noms std ;
entier fn()

statique int stc = 1;
cout << " << stc;
stc = stc + 1;
si (stc > 5)
renvoie 0 ;
fn();

int main()

fn();
renvoie 0 ;

La sortie est : 1 2 3 4 5 .

Remarque : La durée d'un objet statique commence lorsque l'objet a été initialisé, et se termine à la fin du programme. En attendant, l'objet peut être utilisé indirectement, à partir d'une portée différente. Une fois un objet statique initialisé, sa valeur initiale ne peut plus être modifiée, même si sa définition est réévaluée. Dans le code ci-dessus, le stc n'est pas réinitialisé, la prochaine fois qu'il est appelé. La prochaine fois qu'il est appelé, il est incrémenté de "stc = stc + 1;".

Membre de données statiques

Un ensemble de variables et de fonctions connexes peut être placé dans une unité généralisée appelée classe. Si les variables reçoivent des valeurs particulières, la classe devient un objet. Cependant, un objet n'est pas créé en attribuant simplement des valeurs à la variable. La classe est instanciée pour obtenir un objet ; et chaque objet créé a son propre nom différent des autres objets de la même classe. Le programme suivant montre une classe, appelée TheCla et un objet, appelé obj ; il montre également comment l'objet est instancié et utilisé dans la fonction main() :

#inclure
en utilisant l'espace de noms std ;
classe TheCla

Publique:
nombre entier ;
void func (char cha, const char *str)

cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

 ;
int main()

TheCla obj;
obj.nombre = 12 ;
obj.func('$', "500");
renvoie 0 ;

La sortie est :

Il y a 12 livres d'une valeur de 500 $ dans le magasin.

Notez que pour affecter la valeur de 12 à la variable num, l'objet doit être instancié, avant que l'affectation puisse avoir lieu. Il est possible pour le programmeur d'affecter la valeur sans instancier (créer) un objet. Pour ce faire, la variable num devra être déclarée comme statique. Ensuite, il sera accessible en tant que "TheCla::num" sans le nom de l'objet, mais avec le nom de la classe. Le programme suivant illustre cela :

#inclure
en utilisant l'espace de noms std ;
classe TheCla

Publique:
statique const int num = 12 ;
void func (char cha, const char *str)

cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

 ;
int main()

cout << TheCla::num << '\n';
TheCla obj;
obj.func('$', "500");
renvoie 0 ;

La sortie est :

12
Il y a 12 livres d'une valeur de 500 $ dans le magasin.

Notez que pour accéder au membre de données, num dans main(), l'opérateur de résolution de portée, :: devait être utilisé. Pas non plus que la variable num devait être rendue constante et initialisée dans la description de la classe (définition).

Fonction de membre statique

Notez que dans la liste de programmes précédente ci-dessus, pour utiliser la fonction func dans main(), un objet devait être instancié. Il est possible pour le programmeur d'appeler la fonction sans instancier (créer) un objet. Pour ce faire, la définition de la fonction doit être précédée du mot « statique ». Ensuite, il sera accessible en tant que "TheCla::func()" sans le nom de l'objet, mais avec le nom de la classe. Le programme suivant illustre cela pour un membre de données statique et une fonction de membre statique :

#inclure
en utilisant l'espace de noms std ;
classe TheCla

Publique:
statique const int num = 12 ;
static void func (char cha, const char *str)

cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

 ;
int main()

TheCla::func('$', "500");
renvoie 0 ;

La sortie est :

Il y a 12 livres d'une valeur de 500 $ dans le magasin.

Durée de stockage des threads

Thread en tant que fonctionnalité en C++, n'a pas encore été implémenté par le compilateur g++. Ainsi, au lieu d'expliquer cela, la citation de la spécification C++ est donnée comme suit :

  1. Toutes les variables déclarées avec le mot-clé thread_local ont une durée de stockage de thread. Le stockage de ces entités doit durer la durée du fil dans lequel elles sont créées. Il existe un objet ou une référence distinct par thread, et l'utilisation du nom déclaré fait référence à l'entité associée au thread actuel.
  2. Une variable avec une durée de stockage de thread doit être initialisée avant sa première utilisation odr et, si elle est construite, doit être détruite à la sortie du thread."

Conclusion

La durée de vie d'un objet commence lorsque son initialisation est terminée, et se termine lorsque son stockage est libéré. La durée de stockage dynamique commence lorsque le stockage créé par (nouveau type) est initialisé et se termine lorsque l'objet sort de la portée ou est supprimé par « pointeur de suppression ». La durée d'un objet statique commence lorsque l'objet a été initialisé, et se termine à la fin du programme. Une fois un objet statique initialisé, sa valeur initiale ne peut plus être modifiée, même si sa définition est réévaluée. Les membres de données statiques et les membres de fonction statiques sont accessibles en dehors de la description de classe avec "ClassName::name".

Chrys

Ports Open Source des moteurs de jeux commerciaux
Les récréations de moteur de jeu gratuites, open source et multiplateformes peuvent être utilisées pour jouer à d'anciens ainsi qu'à certains des titr...
Meilleurs jeux de ligne de commande pour Linux
La ligne de commande n'est pas seulement votre plus grand allié lorsque vous utilisez Linux, elle peut également être une source de divertissement car...
Meilleures applications de mappage de manette de jeu pour Linux
Si vous aimez jouer à des jeux sur Linux avec une manette de jeu au lieu d'un système de saisie clavier et souris typique, il existe des applications ...