Concepts en C

Cohérence, logique et fonctionnement du C


précédentsommairesuivant

II. Objets

Un objet est un conteneur d'information. Il a donc un caractère très concret puisqu'il est matérialisé par une zone mémoire permettant de stocker cette information. Cette information est une valeur.

L'information peut être structurée lorsque l'objet est construit à partir d'autres objets (objet du type agrégats : tableaux et structures). L'information associée à l'objet est alors l'ensemble des informations stockées par les objets qui le constituent.

II-A. Caractéristiques des objets

II-A-1. Type

Un objet possède un type qui caractérise :

  1. La structure interne de l'objet.

  2. L'information qu'il contient et comment y accéder.

  3. La place nécessaire au stockage de cette information, donc la place que l'objet occupe en mémoire. L'opérateur sizeof nous donne le nombre de bytes occupés en mémoire par l'objet.

  4. Les opérations qui peuvent être effectuées avec cet objet.

Il n'est pas possible de modifier le type d'un objet : Le type de l'objet est fixé à sa création

II-A-2. Adresse

Un objet possède une adresse : C'est une valeur qui repère l'emplacement de l'objet en mémoire. Le codage binaire utilisé pour ce repérage ne nous concerne pas.

  • Pour obtenir l'adresse d'un objet, on dispose de l'opérateur unaire & : l'adresse de l'objet obj est &obj

  • Pour obtenir l'objet situé à une adresse donnée, on utilise l'opérateur unaire * : l'objet à l'adresse adr est *adr (et par conséquent *&Objet est identique à Objet).

  • Ceci implique qu'il existe des valeurs d'un type particulier décrivant l'adresse des objets. Elles seront dites du type "adresse d'un objet de type ..."

Il n'est pas possible de modifier l'adresse d'un objet : elle est fixée au moment de sa création. En d'autres termes, on ne peut pas "déplacer" un objet.

L'opérateur sizeof et l'opérateur unaire & sont les seuls opérateurs définis pour tous les objets, quel que soit leur type. Les objets du genre tableau ne possèdent que ces deux opérateurs. Les objets de type struct possèdent également l'opérateur d'assignation simple =.

II-A-3. Valeur d'un objet

Il faut pouvoir accéder à l'information contenue dans un objet. Cet accès se fait par la propriété qu'il est convenu d'appeler la valeur de l'objet.

Deux cas sont possibles :

  1. La valeur de l'objet est directement l'information stockée par l'objet. C'est le cas de tous les objets à l'exception unique des objets du genre tableau.

    • On peut (si l'objet n'est pas déclaré constant const) modifier la valeur de l'objet, donc l'information qu'il stocke en utilisant, par exemple, l'opérateur d'assignation =.

    • Si l'information est de type T, alors la valeur de l'objet est de type T et l'objet lui-même est dit de type T.

  2. La valeur de l'objet est l'adresse où se trouve placée l'information stockée par l'objet. C'est le cas des seuls objets du genre tableau.

    • L'adresse de l'objet étant, on l'a vu, fixée à sa création et n'étant pas modifiable, on ne peut modifier la valeur d'un objet tableau.

    • Le type de l'objet est alors différent du type de sa valeur : l'objet est du type "tableau de ..." , sa valeur est du type "adresse de..."

En résumé, un objet est caractérisé par :
- son type (non modifiable)
- sa valeur (modifiable si l'objet n'est pas un objet constant ou un tableau)
- son adresse (non modifiable)

II-B. Vie et mort des objets

Un objet existe lorsqu'une zone mémoire lui est allouée (pour lui permettre de stocker son information) et il cesse d'exister lorsqu'elle lui est reprise.
Le programmeur doit être sûr que l'objet qu'il utilise est "vivant". Il doit donc savoir quand l'objet a été créé et quand il a été détruit. Sa durée d'existence est liée au mode de création utilisé.

Les modes possibles de création d'un objet sont :

  1. Par allocation mémoire statique

    • L'objet est déclaré hors de toute fonction (ou est spécifié static ).

    • Il est créé avant même de commencer l'exécution du programme (c'est à dire avant l'invocation de la fonction main).

    • Son information est initialisée par défaut par un code où tous les bits de la mémoire allouée à l'objet sont à 0, mais il est possible d'initialiser l'objet au moment de sa création à une autre valeur.

    • L'objet est repéré par un nom (identificateur).

    • L'objet est détruit automatiquement à la fin du programme.


  2. Par allocation mémoire automatique

    • L'objet (non static) est déclaré dans une fonction.

    • Il est créé automatiquement dans une zone mémoire spéciale appelée pile (stack).

    • Aucune initialisation de la mémoire allouée n'est faite par défaut, mais il est possible d'initialiser l'objet au moment de sa création.

    • L'objet est repéré par un identificateur.

    • Il est automatiquement détruit lorsque l'exécution du bloc { } où il est défini est terminée. C'est donc un objet "temporaire".


  3. Par allocation mémoire dynamique

    • Cette méthode permet de créer un bloc d'objets identiques (bloc qui peut ne comporter qu'un seul objet). La structure du bloc d'objets et les méthodes d'accès à leur information sont celles des tableaux et on parlera souvent de "tableau en allocation dynamique".

    • Ils sont créés sur la demande explicite du programmeur dans une zone mémoire appelée tas (heap) par l'appel à une fonction de la bibliothèque (comme malloc).

    • Dans ce cas, le bloc d'objets n'est pas repéré par un identificateur mais (comme pour les tableaux) par l'adresse du début du bloc d'objets.

    • Il ne sera détruit que sur la demande explicite du programmeur, par appel à une fonction de la bibliothèque (free). Il est de la responsabilité du programmeur de détruire (une et une seule fois !) les objets devenus inutiles ainsi créés afin de rendre disponible l'espace mémoire qu'ils occupaient.

Lors de la création d'un objet, il est nécessaire de préciser la place mémoire nécessaire au stockage de l'information de l'objet. Dans les deux premières méthodes, cette information sera fournie en spécifiant, à sa création, le type de l'objet (ce qui précisera également les opérations qui lui seront applicables) et dans la dernière, elle sera fournie à la fonction d'allocation (souvent par l'intermédiaire de l'opérateur sizeof).

II-C. Accès à un objet

Il n'existe fondamentalement qu'un mécanisme pour accéder à un objet : savoir où il est placé en mémoire, donc connaître son adresse. Toutefois, du point de vue du programmeur, deux possibilités sont offertes :

  1. On connaît l'adresse de l'objet :

    Pour accéder à un objet dont on connaît l'adresse, on utilise l' opérateur unaire *

  2. Un nom (identificateur) a été donné à l'objet au moment de sa création (donc en allocation statique ou automatique).

    Le compilateur alloue la zone mémoire nécessaire à la création de l'objet et connaît donc son emplacement en mémoire : il fera alors lui-même la correspondance entre l'identificateur et l'emplacement en mémoire de l'objet.

L'adresse d'un objet n'est valide que durant la durée de vie de l'objet. C'est pourquoi, par exemple, il ne faut jamais retourner l'adresse d'un objet local à une fonction (donc en allocation automatique).


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.