Ch08

4

Click here to load reader

Transcript of Ch08

Page 1: Ch08

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.

Page 2: Ch08

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.

Page 3: Ch08

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.

Page 4: Ch08

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).