}
cout << "il y a : " << ens.cardinal () << " entiers différents\n" ;
}
À titre indicatif, voici un exemple d’exécution :
donnez 20 entiers
0 2 5 2 8 5 1 8 2 0 7 2 5 5 4 5 0 0 4 5
il y a : 7 entiers différents
3. Telle qu’est actuellement prévue notre classe set_int, si un objet de ce type est
transmis par valeur, soit en argument d’appel, soit en retour d’une fonction, il y a
appel du constructeur de recopie par défaut. Or ce dernier se contente d’effectuer
une copie des membres donnée de l’objet concerné, ce qui signifie qu’on se retrouve
en présence de deux objets contenant deux pointeurs différents sur un même tableau
d’entiers. Un problème va donc se poser, dès lors que l’objet copié sera détruit (ce
qui peut se produire dès la sortie de la fonction) ; en effet, dans ce cas, le tableau
dynamique d’entiers sera détruit, alors même que l’objet d’origine continuera à
« pointer » dessus.
Indépendamment de cela, d’autres problèmes similaires pourraient se poser si la
fonction était amenée à modifier le contenu de l’ensemble ; en effet, on modifierait
alors le tableau d’entiers original, chose à laquelle on ne s’attend pas dans le cas de
la transmission par valeur.
Pour régler ces problèmes, il est nécessaire de munir notre classe d’un constructeur
par recopie approprié, c’est-à-dire tenant compte de la « partie dynamique » de
l’objet (on parle parfois de « copie profonde »). Pour ce faire, on alloue un second
emplacement pour un tableau d’entiers, dans lequel on recopie les valeurs du
premier ensemble. Naturellement, il ne faut pas oublier de procéder également à la
recopie des membres donnée, puisque celle-ci n’est plus assurée par le constructeur
de recopie par défaut (lequel n’est plus appelé, dès lors qu’un constructeur par
recopie a été défini).
Nous ajouterons donc dans la déclaration de notre classe :
set_int (set_int &) ; // constructeur par recopie
Et, dans sa définition :
set_int::set_int (set_int & e) // ou set_int::set_int (const set_int & e)
{
adval = new int [nmax = e.nmax] ; // allocation nouveau tableau
nelem = e.nelem ;
int i ;
for (i=0 ; i
adval[i] = e.adval[i] ;
}
Discussion
175
cout << "il y a : " << ens.cardinal () << " entiers différents\n" ;
}
À titre indicatif, voici un exemple d’exécution :
donnez 20 entiers
0 2 5 2 8 5 1 8 2 0 7 2 5 5 4 5 0 0 4 5
il y a : 7 entiers différents
3. Telle qu’est actuellement prévue notre classe set_int, si un objet de ce type est
transmis par valeur, soit en argument d’appel, soit en retour d’une fonction, il y a
appel du constructeur de recopie par défaut. Or ce dernier se contente d’effectuer
une copie des membres donnée de l’objet concerné, ce qui signifie qu’on se retrouve
en présence de deux objets contenant deux pointeurs différents sur un même tableau
d’entiers. Un problème va donc se poser, dès lors que l’objet copié sera détruit (ce
qui peut se produire dès la sortie de la fonction) ; en effet, dans ce cas, le tableau
dynamique d’entiers sera détruit, alors même que l’objet d’origine continuera à
« pointer » dessus.
Indépendamment de cela, d’autres problèmes similaires pourraient se poser si la
fonction était amenée à modifier le contenu de l’ensemble ; en effet, on modifierait
alors le tableau d’entiers original, chose à laquelle on ne s’attend pas dans le cas de
la transmission par valeur.
Pour régler ces problèmes, il est nécessaire de munir notre classe d’un constructeur
par recopie approprié, c’est-à-dire tenant compte de la « partie dynamique » de
l’objet (on parle parfois de « copie profonde »). Pour ce faire, on alloue un second
emplacement pour un tableau d’entiers, dans lequel on recopie les valeurs du
premier ensemble. Naturellement, il ne faut pas oublier de procéder également à la
recopie des membres donnée, puisque celle-ci n’est plus assurée par le constructeur
de recopie par défaut (lequel n’est plus appelé, dès lors qu’un constructeur par
recopie a été défini).
Nous ajouterons donc dans la déclaration de notre classe :
set_int (set_int &) ; // constructeur par recopie
Et, dans sa définition :
set_int::set_int (set_int & e) // ou set_int::set_int (const set_int & e)
{
adval = new int [nmax = e.nmax] ; // allocation nouveau tableau
nelem = e.nelem ;
int i ;
for (i=0 ; i
}
Discussion
175
