1. Chapitre VIII
Conversions
• En plus des conversions implicites ou explicites (cast) définies dans C, C++ offre la
possibilité de définir des conversions d'un type classe vers un autre type classe ou un
type de base.
• De telles conversions, dites conversions définies par l'utilisateur, peuvent être définies
soit par les constructeurs à un seul argument, soit par la surcharge de l'opérateur de
cast.
• Les conversions, ainsi définies, peuvent être appelées explicitement ou implicitement
par le compilateur. Le compilateur fait appel à l'une des conversions définies par
l'utilisateur, s'il ne peut appliquer une conversion standard.
• Notez que le compilateur cherche à appliquer implicitement une conversion chaque
fois qu'il trouve (dans une initialisation, l'argument d'une fonction, le paramètre de
retour d'une fonction, lors de l'évaluation d'une expression, etc.…) un objet dont le
type ne correspond pas au type attendu.
• D'autre part, le compilateur ne cherche pas des conversions intermédiaires pour
réaliser une autre. Si par exemple une conversion est définie d'un type A vers un type
B, et une autre est définie de ce type B vers un type C, le compilateur ne peut pas
utiliser implicitement ces deux conversions pour réaliser une conversion de A vers C.
2. Conversions 76
VIII.1 Conversion définie par le constructeur
• Un constructeur avec un seul argument réalise une conversion du type de cet argument
vers le type de sa classe, et ce quelque soit le type de cet argument.
• Notez que ce type de conversion ne peut être utilisé pour définir les conversions de
type classe vers un type de base.
Exemple 8.1 : (EXP08_01.CPP)
L'exemple suivant montre comment le constructeur de la classe point à un seul
argument de type int définit une conversion de int vers point
class point{
int x;
int y;
public:
point(): x(0), y(0){}
point(int abs ): x(abs), y(abs){}
point(int abs, int ord): x(abs), y(ord){}
void affiche(){
cout << "(" << x << "," << y << ")" << endl;
}
};
// fonction avec argument de type point
void fct(point pt){
pt.affiche();
}
//--------------------- TEST
int main()
{
point a;
// conversion implicite de int -> point lors d'une affectation
a = 6;
a.affiche();
// conversion implicite de int -> point lors de l'appel d'une fonction
fct(7);
// conversion explicite
((point)5).affiche();
return 0;
}
VIII.2 Opérateur de cast
• Pour définir l'opérateur de conversion d'une classe T vers un type A, on utilise la
fonction membre :
operator A ();
• Notez que :
Cette fonction membre doit retourner une valeur de type A.
le type de retour ne doit pas figurer dans l'entête de la fonction.
la fonction ne prend aucun argument.
3. Conversions 77
Exemple 8.2 : (EXP08_02.CPP)
On considère dans cet exemple une conversion de point vers un entier
class point{
int x;
int y;
public:
point(int abs = 0, int ord = 0):x(abs), y(ord){}
operator int(){
return x;
}
};
//--------------------- TEST
int main()
{
point a(5,6);
int i,j;
// conversion implicite de point -> int
i = a;
cout << i << endl; // i = 5
// conversion lors d'une expression
j = a + 4; // j = 9
cout << j << endl;
return 0;
}
VIII.3 Problèmes posées par le transtypage
• Les conversions définies par l'utilisateur doivent être sans ambiguïtés, autrement dit,
on ne peut avoir plusieurs chaînes de conversions qui conduisent vers un même type :
Plusieurs problèmes peuvent être posés, lorsqu’on définit dans une classe des conversions.
On peur citer par exemple, les cas suivants :
1. Une classe qui définit deux conversions vers des types de bases :
Exemple 8.3 : (EXP08_03.CPP)
On définit pour une classe T, deux conversions, une vers int et l’autre vers double.
class T{
int n;
public:
T(int k = 0): n(0){}
operator int(){return n;}
operator double(){ return (double) n;}
};
int main()
{
T a;
double r;
r = 2.5 + a; //ambiguïté
return 0;
}
Ici, deux opérateurs prédéfinis peuvent être appliqués operator+(double,double)
et operator+(double,int). Par suite, le compilateur ne peut choisir entre l’une des
deux.
4. Conversions 78
2. Une classe qui définit une conversion vers un type de base, et surcharge certains
opérateurs :
Exemple 8.4 : (EXP08_04.CPP)
On définit pour la classe point, une conversion vers int et on surcharge l’opérateur +.
class point{
int x;
int y;
public:
point(): x(0), y(0){}
point(int abs ): x(abs), y(abs){}
point(int abs, int ord): x(abs), y(ord){}
operator int() {return x;}
friend point operator+(point,point);
};
point operator+(point u, point v){
point temp;
temp.x = u.x + v.x;
temp.y = u.y + v.y;
return temp;
}
//--------------------- TEST
int main()
{
point a(5,6);
point b;
b = a + 4; //ambiguïté
return 0;
}
Ici, le compilateur ne peut choisir entre les deux opérateurs candidats
operator+(point,point) et operator+(int,int).