move 'durée de vie' chapter to reflect the english version

This commit is contained in:
Raphaël JAKSE 2015-08-31 10:10:29 +02:00
parent 07ff8ea8b8
commit 55137fb446
2 changed files with 55 additions and 54 deletions

View File

@ -2,23 +2,24 @@
title = Durées de vie et opérations fondamentales
partAs = chapitre
translator = "Raphaël Jakse"
proofreader = "Stéphane Goujet"
]
Nous verrons bientôt les structures, la fonctionnalité de base qui permet au programmeur de définir des types spécifiques à une application. Les structures sont faites pour combiner des types fondamentaux et d'autres structures ensemble pour définir des types de plus haut niveau qui se comportent selon des besoins spécifiques des programmes. Après les structures, nous verrons les classes, qui sont la base de la programmation orientée objet en D.
Avant de parler de structures et de classes, nous allons d'abord aborder des notions importantes. Ces notions aideront à comprendre les structures, les classes et certaines de leurs différences.
Nous avons appelé toute partie de donnée qui représente une idée dans un programme une [* variable]. À certains endroits, nous avons nommé des variables de type structure ou classe des [* objets]. On va continuer à les appeler des variables dans ce chapitre.
Nous avons appelé toute donnée qui représente une idée dans un programme une [* variable]. À certains endroits, nous avons nommé des variables de type structure ou classe des [* objets]. On va continuer à les appeler des variables dans ce chapitre.
Même si ce chapitre n'aborde que les types fondamentaux, les tranches et les tableaux associatifs, ces notions s'appliquent également aux types définis par l'utilisateur.
[ = Durée de vie d'une variable
Le temps entre la définition d'une variable et sa [* disparition] est sa [* durée de vie]. Même si c'est le cas pour beaucoup de types, [* devenir indisponible] et [* disparaître] n'ont pas besoin d'arriver en même temps.
Le temps écoulé entre la définition d'une variable et sa [* finalisation] est sa [* durée de vie]. Même si c'est le cas pour beaucoup de types, [* devenir indisponible] et [* être finalisé] ne se passent pas nécessairement en même temps.
Vous devriez vous souvenir du [[part:espace_de_nom | chapitre sur les espaces de noms] de comment les variables deviennent indisponibles. Dans les cas simples, quitter la portée dans laquelle une variable a été définie rend cette variable indisponible.
Si vous vous souvenez du [[part:espace_de_nom | chapitre sur les espaces de noms], vous vous rappelez de la manière dont les variables deviennent indisponibles. Dans les cas simples, quitter la portée dans laquelle une variable a été définie rend cette variable indisponible.
Considérons l'exemple suivant comme un rappel :
Considérons l'exemple suivant comme un rappel~ :
[code=d <<<
void testVitesse()
@ -34,7 +35,7 @@ Même si ce chapitre n'aborde que les types fondamentaux, les tranches et les ta
La vie de la variable [c vitesse] dans ce code prend fin lorsque l'on sort de la fonction [c testVitesse]. Il y a une seule variable dans le code suivant et elle prend 10 valeurs différentes, de 100 à 109.
En ce qui conserne la durée de vie des variables, le code suivant est très différent comparé au précédent :
En ce qui conserne la durée de vie des variables, le code suivant est très différent comparé au précédent~ :
[code=d <<<
void testVitesse()
@ -51,18 +52,18 @@ Même si ce chapitre n'aborde que les types fondamentaux, les tranches et les ta
[ = Durée de vie d'un paramètre
La durée de vie d'un paramètre dépend de ses qualificateurs :
La durée de vie d'un paramètre dépend de ses qualificateurs~ :
- [p [c ref] : | le paramètre est seulement un alias de la variable qui est indiquée lors de l'appel de la fonction. Les paramètres [c refs] n'affectent pas la durée de vie des variables.]
- [p [c ref]~ : | le paramètre est seulement un alias de la variable qui est indiquée lors de l'appel de la fonction. Les paramètres [c ref]s n'affectent pas la durée de vie des variables.]
- [p [c in] : | pour les [* types passés par valeur], la vie d'un paramètre commence en entrant dans la fonction et prend fin lorsque l'on en sort. Pour les [* types passés par référence], la vie du paramètre est la même qu'avec [c ref] (nous verrons les types passés par valeurs et les types passés par référence dans le chapitre suivant).]
- [p [c in]~ : | pour les [* types valeur], la vie d'un paramètre commence en entrant dans la fonction et prend fin lorsque l'on en sort. Pour les [* types référence], la vie du paramètre est la même qu'avec [c ref].]
- [p [c out] : | pareil que pour [c ref], le paramètre n'est qu'un alias de la variable qui est indiquée lors de l'appel de la fonction. La seule différence est que la variable est mise à sa valeur [c .init] automatiquement en entrant dans la fonction.]
- [p [c out]~ : | pareil que pour [c ref], le paramètre n'est qu'un alias de la variable qui est indiquée lors de l'appel de la fonction. La seule différence est que la variable est mise à sa valeur [c .init] automatiquement en entrant dans la fonction.]
- [p [c lazy] : | la vie du paramètre commence quand le paramètre est utilisé et prend aussitôt fin.]
- [p [c lazy]~ : | la vie du paramètre commence quand le paramètre est utilisé et prend aussitôt fin.]
L'exemple suivant utilise ces quatre types de paramètres et explique leur durée de vie dans les commentaires :
L'exemple suivant utilise ces quatre types de paramètres et explique leur durée de vie dans les commentaires~ :
[code=d <<<
void main()
@ -93,7 +94,7 @@ Même si ce chapitre n'aborde que les types fondamentaux, les tranches et les ta
lazy int p_lazy) /* La vie de p_lazy commence lors de
* son utilisation et prend fin lorsque
* son utilisation prend fin. sa valeur
* son utilisation prend fin. Sa valeur
* est recalculée en appelant unCalcul()
* à chaque fois que p_lazy est utilisé
* dans la fonction. */
@ -111,23 +112,23 @@ Même si ce chapitre n'aborde que les types fondamentaux, les tranches et les ta
]
[ = Opérations fondamentales
Indépendamment de son type, il y a trois opérations fondamentales au cours de la vie d'une variable :
Indépendamment de son type, il y a trois opérations fondamentales au cours de la vie d'une variable~ :
- [** Initialisation] : le début de sa vie
- [** Finalisation] : la fin de sa vie
- [** Affectation] : changer sa valeur.
- [** initialisation]~ : le début de sa vie~ ;
- [** finalisation]~ : la fin de sa vie~ ;
- [** affectation]~ : changer sa valeur.
Pour être considéré comme un objet, elle doit déjà être initialisée. Il peut y avoir des opérations finales pour certains types. La valeur d'une variable peut changer au cours de sa vie.
Pour être considéré comme un objet, elle doit d'abord être initialisée. Il peut y avoir des opérations finales pour certains types. La valeur d'une variable peut changer au cours de sa vie.
[ = Initialisation
Tout variable doit être initialisée avant d'être utilisée. L'initialisation implique deux étapes :
- [** réserver de l'espace pour la variable] : cet espace est l'endroit dans lequel la valeur de la variable est stockée en mémoire.
- [** Construction] : fixer la première valeur de la variable dans cet espace (ou les premières valeurs des membres des structures et des classes).
Tout variable doit être initialisée avant d'être utilisée. L'initialisation implique deux étapes~ :
- [** réservation de l'espace pour la variable]~ : cet espace est l'endroit dans lequel la valeur de la variable est stockée en mémoire~ ;
- [** construction]~ : fixer la première valeur de la variable dans cet espace (ou les premières valeurs des membres des structures et des classes).
Toute variable vit à un endroit en mémoire qui lui est réservé. Une partie du code que le compilateur génère sert à réserver de l'espace pour chaque variable.
Toute variable vie à un endroit en mémoire qui lui est réservé. Une partie du code que le compilateur génère sert à réserver de l'espace pour chaque variable.
considérons la variable suivante :
Considérons la variable suivante~ :
[code=d <<<
int vitesse = 123;
@ -142,13 +143,13 @@ Même si ce chapitre n'aborde que les types fondamentaux, les tranches et les ta
--+-----+-----+-----+--
>>>]
L'endroit dans lequel la variable est placé dans la mémoire a une adresse. En un sens, la variable vie à cette adresse. Quand la valeur d'une variable est changée, la nouvelle valeur est stockée à la même place :
L'endroit dans lequel la variable est placé dans la mémoire a une adresse. En un sens, la variable vit à cette adresse. Quand la valeur d'une variable est changée, la nouvelle valeur est stockée à la même place~ :
[code=d <<<
++vitesse;
>>>]
La nouvelle valeur se retrouve au même endroit, là où l'ancienne valeur était stockée :
La nouvelle valeur se retrouve au même endroit, là où l'ancienne valeur était stockée~ :
[pre <<<
--+-----+-----+-----+--
@ -158,27 +159,27 @@ Même si ce chapitre n'aborde que les types fondamentaux, les tranches et les ta
La construction est nécessaire pour préparer l'utilisation des variables. Comme une variable ne peut pas être utilisée de façon fiable avant d'avoir été construite, ceci est fait par le compilateur automatiquement.
Les variables peuvent être construite de trois manières :
- [** Par leur valeur par défaut] : quand le programmeur ne spécifie pas une valeur explicite
- [** En copiant] : quand la variable est construite comme étant la copie d'une variable du même type
- [** Par une valeur spécifique] : quand le programmeur ne spécifie pas une valeur explicitement.
Les variables peuvent être construites de trois manières~ :
- [** par leur valeur par défaut]~ : quand le programmeur ne spécifie pas une valeur explicite~ ;
- [** en copiant]~ : quand la variable est construite comme étant la copie d'une variable du même type~ ;
- [** par une valeur spécifique]~ : quand le programmeur spécifie une valeur explicitement.
Quand une valeur n'est pas spécifiée, la valeur de la variable est la valeur [* par défaut] de sont type, c-a-d sa valeur [c .init].
Quand une valeur n'est pas spécifiée, la valeur de la variable est la valeur [* par défaut] de son type, c.-à-d. sa valeur [c .init].
[code=d <<<
int vitesse;
>>>]
La valeur de [c vitesse] ci-avant est [c int.init], qui se trouve être zéro. Naturellement, une variable qui est construite par sa valeur par défaut peut prendre d'autres valeurs durant sa vie (sauf si elle est [c immutable]).
La valeur de [c vitesse] est [c int.init], qui se trouve être zéro. Naturellement, une variable qui est construite par sa valeur par défaut peut prendre d'autres valeurs durant sa vie (sauf si elle est [c immutable]).
[code=d <<<
File file;
File fichier;
>>>]
Avec la définition précédente, la variable [c file] est un objet [c File] qui n'a pas encore été associé à un fichier du fichier système. Elle n'est pas utilisable tant qu'elle est modifiée pour être associée à un fichier.
Avec la définition précédente, la variable [c fichier] est un objet [c File] qui n'a pas encore été associé à un fichier du système de fichiers. Elle reste inutilisable jusqu'à ce qu'elle soit modifiée pour être associée à un fichier.
Les variables sont parfois construite comme des copies d'une autre variable :
Les variables sont parfois construites comme des copies d'une autre variable~ :
[code=d <<<
int vitesse = autreVitesse;
@ -186,16 +187,16 @@ Même si ce chapitre n'aborde que les types fondamentaux, les tranches et les ta
[c vitesse] est ici construite par la valeur de [c autreVitesse].
Comme nous le verrons dans des chapitres ultérieurs, cette opération a une signification différente pour les variables de type classe :
Comme nous le verrons dans des chapitres ultérieurs, cette opération a une signification différente pour les variables de type classe~ :
[code=d <<<
auto variableClasse = autreVariableClasse;
>>>]
Même si [c variableClasse] commence sa vie comme une copie de [c variableAutreClasse], il y a une différence fondamentale avec les classe : bien que [c vitesse] et [c autreVitesse] soient des valeurs distinctes, [c variableClasse] et [c variableAutreClasse] donnent toutes deux accès à la même valeur. C'est la différence fondamentale entre les types valeurs et les types références. Nous verrons cela dans le chapitre suivant.
Même si [c variableClasse] commence sa vie comme une copie de [c variableAutreClasse], il y a une différence fondamentale avec les classes~ : bien que [c vitesse] et [c autreVitesse] soient des valeurs distinctes, [c variableClasse] et [c variableAutreClasse] donnent toutes deux accès à la même valeur. C'est la différence fondamentale entre les types valeurs et les types références. Nous verrons cela dans le chapitre suivant.
Enfin, les variables peuvent être construites par la valeur d'une expression d'un type compatible :
Enfin, les variables peuvent être construites par la valeur d'une expression d'un type compatible~ :
[code=d <<<
int vitesse = unCalcul();
@ -205,35 +206,35 @@ Même si ce chapitre n'aborde que les types fondamentaux, les tranches et les ta
]
[ = Finalisation
La finalisation est l'ensemble des opérations finales qui sont exécutées pour une variable ainsi que libérer la mémoire qu'elle prend :
- [** Destruction] : les opérations finales qui doivent être exécutées pour la variable
- [** Libérer la mémoire] : on reprend la case mémoire que la variable occupait pendant sa vie.
La finalisation est l'ensemble des opérations finales qui sont exécutées pour une variable ainsi que la libération de la mémoire qu'elle occupait~ :
- [** destruction]~ : les opérations finales qui doivent être exécutées pour la variable ;
- [** libération de la mémoire]~ : on reprend la case mémoire que la variable occupait pendant sa vie.
Pour les types fondamentaux, il n'y a pas d'opération finale à exécuter. Par exemple, la valeur d'une variable de type [c int] n'est pas remise à zéro. Pour de telle variable, il n'y a que la libération de la mémoire, qui pourra être utilisée pour d'autres variables plus tard.
Pour les types fondamentaux, il n'y a pas d'opération finale à exécuter. Par exemple, la valeur d'une variable de type [c int] n'est pas remise à zéro. Pour de telles variables, il n'y a que la libération de la mémoire, qui pourra être utilisée pour d'autres variables plus tard.
En revanche, certains types de variable nécessitent des opérations spéciales pendant la finalisation. Par exemple, un objet [c File] aurait besoin d'écrire les caractères qui sont toujours dans son tampon de sortie sur le disque et de notifier au système de fichier qu'il n'utilise plus le fichier. Ces opérations sont la destruction d'un objet [c File].
En revanche, certains types de variables nécessitent des opérations spéciales pendant la finalisation. Par exemple, un objet [c File] aura besoin d'écrire sur le disque les caractères qui sont toujours dans son tampon de sortie et de notifier au système de fichiers le fait qu'il n'utilise plus le fichier. Ces opérations sont la destruction d'un objet [c File].
Les opérations finales des tableaux sont d'un niveau plus haut : avant de finaliser le tableau, ses éléments doivent d'abord être détruits. Si les éléments sont d'un type fondamental simple comme [c int], il n'y a alors pas de d'opération finale spéciale à effectuer. Si les éléments sont d'un type structure ou classe qui ont besoin d'être finalisés, ces opérations sont alors exécutés pour chaque élément.
Les opérations finales des tableaux sont d'un niveau un peu plus haut~ : avant de finaliser le tableau, ses éléments doivent d'abord être détruits. Si les éléments sont d'un type fondamental simple comme [c int], il n'y a alors pas de d'opération finale spéciale à effectuer. Si les éléments sont d'un type structure ou classe qui a besoin d'être finalisé, ces opérations sont alors exécutées pour chaque élément.
Les tableaux associatifs sont similaires aux tableaux. De plus, leurs clés peuvent également avoir besoin d'être finalisés s'ils sont d'un type qui nécessite une destruction.
Les tableaux associatifs sont similaires aux tableaux. De plus, leurs clés peuvent également avoir besoin d'être finalisées si elles sont d'un type qui nécessite une destruction.
[p Le ramasse-miette : | D est un langage géré par un ramasse-miettes. Dans de tels langages, finaliser un objet ne nécessite pas d'être fait explicitement par le programmeur. Quand la vie d'une variable se termine, sa finalisation est automatiquement géré par le ramasse-miettes. Nous verrons le ramasse-miettes et la gestion spéciale de la mémoire dans un chapitre ultérieur.]
[p Le ramasse-miettes~ : | D est un langage géré par un ramasse-miettes. Dans de tels langages, finaliser un objet ne nécessite pas d'être fait explicitement par le programmeur. Quand la vie d'une variable se termine, sa finalisation est automatiquement gérée par le ramasse-miettes. Nous verrons le ramasse-miettes et la gestion spéciale de la mémoire dans un chapitre ultérieur.]
Les variables peuvent être finalisées de deux manières :
- [p quand leur vie prend fin : | la finalisation se passe lors de la fin de vie de la variable.]
- [p un moment dans le futur : | La finalisation se passe à un moment indéterminé du futur et elle est faite par le ramasse-miettes.]
Les variables peuvent être finalisées de deux manières~ :
- [p quand leur vie prend fin~ : | la finalisation se passe lors de la fin de vie de la variable~ ;]
- [p un moment dans le futur~ : | la finalisation se passe à un moment indéterminé du futur et elle est faite par le ramasse-miettes.]
La manière par laquelle une variable est finalisée dépend surtout de son type. Certains types de variables comme les tableaux, les tableaux associatifs et les classes sont normalement détruits par le ramasse-miettes à un certain point dans le futur.
La manière de laquelle une variable est finalisée dépend surtout de son type. Certains types de variables comme les tableaux, les tableaux associatifs et les classes sont normalement détruits par le ramasse-miettes à un certain point dans le futur.
]
[ = Affectation
L'autre opération fondamentale qu'une variable subit dans sa vie est l'affectation.
Pour les types simples fondamentaux, l'affectation est simplement le changement de sa valeur. Comme nous l'avons vu ci-dessus dans la représentation de la mémoire, une variable de type [c int] prendrait la valeur 124 au lieu de 123. Cependant, plus généralement, l'affectation consiste en deux étapes, qui ne sont pas forcément exécutées dans l'ordre suivant :
Pour les types simples fondamentaux, l'affectation est simplement le changement de sa valeur. Comme nous l'avons vu ci-dessus dans la représentation de la mémoire, une variable de type [c int] prendrait la valeur 124 au lieu de 123. Cependant, plus généralement, l'affectation consiste en deux étapes, qui ne sont pas forcément exécutées dans l'ordre suivant~ :
- [** Destruction de l'ancienne valeur]
- [** Construction de la nouvelle valeur]
- [** destruction de l'ancienne valeur~ ;]
- [** construction de la nouvelle valeur.]
Ces deux étapes ne sont pas importantes pour les types fondamentaux puisqu'ils n'ont pas besoin de destruction. Pour les types qui nécessitent une destruction, il est important de se souvenir que l'affectation est une combinaison des deux étapes ci-avant.
Ces deux étapes ne sont pas importantes pour les types fondamentaux puisqu'ils n'ont pas besoin de destruction. Pour les types qui nécessitent une destruction, il est important de se souvenir que l'affectation est une combinaison de ces deux étapes.
]
]

View File

@ -34,6 +34,7 @@ switch switch
enum enum
functions fonctions
const_and_immutable const_et_immutable
values_vs_references valeur_vs_reference
function_parameters parametres_de_fonctions
lvalue_rvalue lvalue_rvalue
lazy_operators operateurs_paresseux
@ -44,7 +45,6 @@ assert assert
unit_testing tests_unitaires
contracts contrats
lifetimes durees_vie
values_vs_references valeur_vs_reference
null_is null_is
cast cast
parameter_flexibility flexibilite_parametres