next up previous contents index
Next: Libération et glanage d'objets Up: No Title Previous: Files et parcours en

Clonage d'objets

  Contrairement aux langages orientés objet (tels C++, Java) qui traitent, en principe, tous leurs objets de façon uniforme, C distingue différentes catégories d'objet en ce qui concerne certaines opérations, notamment l'affectation et la définition.

Si i est une variable de type int, la définition

  int j = i;

crée un nouvel objet (<< nouveau >> au sens de distinct de i en mémoire) et lui donne la même valeur qu'à i. L'initialisation peut être faite ultérieurement par affectation :

  int j;
  ...
  j = i;

Dans le cas d'un tableau, seule l'initialisation au moment de la définition est permise, et seulement par des constantes :

  int s[] = { 1, 2, 3, 4 };

Les initialisation et affectation suivantes sont illicites :

  int t[] = s;
  t = { 1, 2, 3, 4 };
  t = s;

La dernière affectation est couramment réalisée par un appel de fonction :

  tableau_copie(4, t, s);

Dans le cas des struct, C permet aussi bien l'initialisation que l'affectation, et c'est une copie de l'objet qui est réalisée. Cela est utile quand les objets d'une structure de données sont exactement représentés par des valeurs d'un type struct : nombres complexes, etc.

Dans d'autres cas, par exemple pour nos arbres binaires, la copie d'une structure tree_cell n'entraine pas une copie de l'arbre complet, mais seulement de la cellule représentant la racine :

    tree_cell *c = tree_cons(0, 
                      tree_cons(1,NULL,NULL),
                      tree_cons(2,NULL,NULL));
    tree_cell *c1 = c;
    tree_cell s = *c;


  
Figure 27: Partage de sous-objets par copie partielle
\begin{figure}
 \begin{center}
 \leavevmode
 
\fbox {
 \epsfig{file=fig/cell_share.eps}
 }
 \end{center} \end{figure}

Alors que c1 et c désignent le même objet, la définition de s crée une nouvelle structure, mais les objets au deuxième niveau de l'arbre sont identiques : il y a partage de sous-objets (figure 27). Une modification d'un sous-objet de s revient donc à une modification de c et de c1, ce qui n'est pas toujours souhaité.

  Il faut donc programmer explicitement une fonction, dite de clonage , qui traverse l'arbre et qui effectue des copies de toutes les structures, et pas seulement de celle qui figure à sa racine. Un parcours en profondeur donne la fonction suivante :

tree_cell *tree_clone(tree_cell *p) {
  tree_cell *t = NULL;

  if (!is_empty_cell(p)) {
    t = tree_cons(p->label, 
           tree_clone(p->left), 
           tree_clone(p->right));
    }
  return t;
}


  
Figure 28: Clonage d'un arbre
\begin{figure}
 \begin{center}
 \leavevmode
 
\fbox {
 \epsfig{file=fig/cell_clone.eps}
 }
 \end{center} \end{figure}

Elle pourra servir aussi bien dans la définition d'un arbre (figure 28) que comme membre droit d'une affectation :

    tree_cell *c = tree_cons(0, 
                      tree_cons(1,NULL,NULL),
                      tree_cons(2,NULL,NULL));
    tree_cell *c3, *c2 = tree_clone(c);
    ...
    c3 =  tree_clone(c2);

next up previous contents index
Next: Libération et glanage d'objets Up: No Title Previous: Files et parcours en
Jean-Philippe Chancelier
9/29/1998