INFO-F-105 Language de programmation I Séance VI Jérôme Dossogne Année académique 2008 2009 Un grand merci à Yves Roggeman pour ses relectures et remarques des codes et commentaires qui ont contribuées significativement à accroitre la qualité des exercices et des solutions de cette séance.
Table des matières 1 Table des matières 1 Question 01 - Des pommes et des poires 1 2 Question 02 - Pommes, poires et oranges 1 3 Question 03 - Le mot-clef explicit 2 4 Question 04 - -fno-elide-constructors : Return Value Optimization 2 5 Question 05 - Etudiants 2 6 Question 06 - Compteur 8 7 Question 07 - Expressions, L/Rvalue 8
Liste des codes 2 Liste des codes 1 Question 01 - Des pommes et des poires : Illustration d ambiguïté à la conversion 1 (src :linuxtopia.org)......................................... 1 2 Question 02 - Pommes, poires et oranges : Illustration d ambiguïté à la conversion 2 (src :linuxtopia.org)......................................... 2 3 Question 03 - Le mot-clef explicit 1 (src :glenmccl.com).................. 3 4 Question 03 - Le mot-clef explicit 2 (src :hardware.fr).................... 4 5 Question 03 - Le mot-clef explicit 2 (src :hardware.fr).................... 4 6 Question 03 - Le mot-clef explicit 2 (src :hardware.fr).................... 5 7 Question 04 - -fno-elide-constructors : Return Value Optimization (src :devshed.com).. 5 8 Question 04 - -fno-elide-constructors : Return Value Optimization (src :devshed.com).. 5 9 Question 04 - -fno-elide-constructors : Return Value Optimization (src :devshed.com).. 6 10 Question 05 - Etudiants : Attributs d une classe....................... 6 11 Question 05 - Etudiants : Attributs d une classe....................... 6 12 Question 05 - Etudiants : Attributs d une classe....................... 7 13 Question 05 - Etudiants : Attributs d une classe....................... 7 14 Question 05 - Etudiants : Attributs d une classe....................... 7 15 Question 06 - Compteur : Opérateurs postfixe, infixe, interne, externe (+, +=)....... 8 16 Question 06 - Compteur : Opérateurs postfixe, infixe, interne, externe (+, +=)....... 9 17 Question 06 - Compteur : Opérateurs postfixe, infixe, interne, externe (+, +=)....... 10 18 Question 07 - Expressions, L/Rvalue............................. 11
2 QUESTION 02 - POMMES, POIRES ET ORANGES 1 Vous êtes consultant(e) dans une entreprise et celle-ci fait appel à votre expertise pour étudier les codes sources ci-dessous, les annoter de remarques pertinentes et remettre à l entreprise vos suggestions et conclusions. 1 1. Question 01 : opérateur de conversion A B présent dans A et dans B 2. Question 02 : overload d une fonction et multiples opérateurs de conversion dans une class 3. Question 03 : le mot clef explicit 4. Question 04 : -fno-elide-constructors, Return Value Optimization 5. Question 05 : attribut de class vs variable globale, notation : pour les constructeurs 6. Question 06 : opérateurs postfixe, infixe, interne, externe (+, +=) 7. Question 07 : Lvalue, Rvalue 1 Question 01 - Des pommes et des poires Code à étudier voir : Code 1 Code 1 Question 01 - Des pommes et des poires : Illustration d ambiguïté à la conversion 1 (src :linuxtopia.org) class Orange; class Apple public: operator Orange() const; ; class Orange public: Orange(Apple); ; void f(orange) int main() Apple a; f(a); 2 Question 02 - Pommes, poires et oranges Code à étudier voir : Code 2 1. Chaque question est à étudier indépendemment. La source des codes pouvant varier, ne soyez pas étonné si les conventions de notation font de même. Il va falloir s y habituer
2 QUESTION 02 - POMMES, POIRES ET ORANGES 2 Code 2 Question 02 - Pommes, poires et oranges : Illustration d ambiguïté à la conversion 2 (src :linuxtopia.org) class Orange Orange(Pear); ; class Pear operator Orange() const; ; class Apple public: operator Orange() const; operator Pear() const; ; void eat(orange); void eat(pear); void eat(orange, Pear); int main() // Question 1 Apple c; eat(c); // Question 2 Orange o; Pear p; eat(o,o); eat(p,p);
3 QUESTION 03 - LE MOT-CLEF EXPLICIT 3 3 Question 03 - Le mot-clef explicit Class A Code à étudier voir : Code 3 La société veut s assurer que les conversions soient voulues et explicitement demandée. Quelles modifications apporteriez vous pour cela? Code 3 Question 03 - Le mot-clef explicit 1 (src :glenmccl.com) class A public: A(int) ; void f(a) void g() A a1 = 37; A a2 = A(47); A a3(57); a1 = 67; f(77); // Objectif voulu // void g() // // A a1 = A(37); // // A a2 = A(47); // // A a3(57); // // a1 = A(67); // // f(a(77)); // classe foo Code à étudier voir : Code 4, Code 5, Code 6
3 QUESTION 03 - LE MOT-CLEF EXPLICIT 4 Code 4 Question 03 - Le mot-clef explicit 2 (src :hardware.fr) class Foo int i; public: Foo() : i(-1) cout << "Constructeur trivial" << " &" << &i << endl; Foo(int j) : i(j) cout << "Constructeur i = " << i << " &" << &i << endl; Foo(const Foo &f) : i(f.i) cout << "Constructeur de copie i = " << i << " &" << &i << " (source &" << &f.i << ')' << endl; ~Foo() cout << "~Destructeur i = " << i << " &" << &i << endl; ; Foo& operator+=(const Foo &other) this->i+=other.i; return *this; Code 5 Question 03 - Le mot-clef explicit 2 (src :hardware.fr) Foo operator+(const Foo &f, const Foo &g) cout << "operator+(foo, Foo)" << endl; Foo tmp(f); tmp+=g; return tmp; Foo dawa(foo f) return 5;
4 QUESTION 04 - -FNO-ELIDE-CONSTRUCTORS : RETURN VALUE OPTIMIZATION 5 Code 6 Question 03 - Le mot-clef explicit 2 (src :hardware.fr) int main() Foo a; Foo b(2); Foo c=3; Foo d(b); b+4; dawa(5); 4 Question 04 - -fno-elide-constructors : Return Value Optimization Code à étudier voir : Code 7, Code 8, Code 9 Code 7 Question 04 - -fno-elide-constructors : Return Value Optimization (src :devshed.com) class stmt public: stmt() std::cout << "Constructor called" << std::endl; m_id = "Original"; stmt(const stmt &st) std::cout << "Copy constructor" << std::endl; const char * id() return m_id.c_str(); private: std::string m_id; ; Le comportement du programme ci-dessous semble suspect à un de vos collègues programmeur. Il vous pose la question suivante : Pourquoi le constructeur de copie n est-il pas appelé là où il devrait? Dans le code qui suit, je m attendais à voir un appel au constructeur de copie car dans la méthode db::prepare(), un objet de type stmt est renvoyé par valeur. Et pourtant, je remarque qu il n est pas appelé. Pourquoi est-ce ainsi, que puis-je faire et que dois-je en déduire à l avenir?
6 QUESTION 06 - COMPTEUR 6 Code 8 Question 04 - -fno-elide-constructors : Return Value Optimization (src :devshed.com) class db public: stmt prepare() stmt s; return s; ; Code 9 Question 04 - -fno-elide-constructors : Return Value Optimization (src :devshed.com) int main(int argc, char * argv[]) stmt s; db d; std::cout << "first: " << s.id() << std::endl; s = d.prepare(); std::cout << "second: " << s.id() << std::endl; return 0; 5 Question 05 - Etudiants Code à étudier voir : Code 10, Code 11, Code 12, Code 13, Code 14 Code 10 Question 05 - Etudiants : Attributs d une classe class Etudiant public : Etudiant(); Etudiant(int nombredecours); void initialisernotes(); private : int i; int * notes; int nombredecours; ; 6 Question 06 - Compteur Code à étudier voir : Code 15, Code 16, Code 17
6 QUESTION 06 - COMPTEUR 7 Code 11 Question 05 - Etudiants : Attributs d une classe Etudiant::Etudiant() nombredecours = 0; notes = NULL; Etudiant::Etudiant(int nombredecours) this->nombredecours = nombredecours; notes = new int[nombredecours]; void Etudiant::initialiserNotes() for(i = 0; i < nombredecours; ++i) cin >> notes[i]; Code 12 Question 05 - Etudiants : Attributs d une classe class BinomeDEtudiants public : BinomeDEtudiants(); BinomeDEtudiants(Etudiant prem, Etudiant sec); private : Etudiant prem; Etudiant sec; ; Code 13 Question 05 - Etudiants : Attributs d une classe BinomeDEtudiants::BinomeDEtudiants() BinomeDEtudiants::BinomeDEtudiants(Etudiant prem, Etudiant sec) this->prem = prem; this->sec = sec; Code 14 Question 05 - Etudiants : Attributs d une classe int main() Etudiant johndoe(4); Etudiant janedoe(4); BinomeDEtudiants does(janedoe,johndoe); return 0;
7 QUESTION 07 - EXPRESSIONS, L/RVALUE 8 Code 15 Question 06 - Compteur : Opérateurs postfixe, infixe, interne, externe (+, +=) class Compteur public : Compteur(); Compteur(int cpt); Compteur(const Compteur& cpt); Compteur& operator=(const Compteur& compt); Compteur operator+(const Compteur& compt); Compteur& operator+=(const Compteur& compt); Compteur& operator++(); Compteur operator++(int); ; void affichage(); private : int cpt; 7 Question 07 - Expressions, L/Rvalue Code à étudier voir : Code 18 Un collègue vous demande votre aide, il a du mal à comprendre le concept d expression, de L/Rvalue,... et souhaiterait que vous lui indiquiez sur le code à étudier où se trouvent chacune d entre elles.
7 QUESTION 07 - EXPRESSIONS, L/RVALUE 9 Code 16 Question 06 - Compteur : Opérateurs postfixe, infixe, interne, externe (+, +=) Compteur::Compteur() : cpt(0) Compteur::Compteur(int cpt) : cpt(cpt) Compteur::Compteur(const Compteur& compt) : cpt(compt.cpt) Compteur& Compteur::operator=(const Compteur& compt) if(this!= &compt) cpt = compt.cpt; return *this; Compteur Compteur::operator+(const Compteur& compt) return Compteur(cpt+compt.cpt); Compteur& Compteur::operator+=(const Compteur& compt) cpt += compt.cpt; return *this; Compteur& Compteur::operator++() cpt++; return *this; Compteur Compteur::operator++(int pasutilise) Compteur tmp(*this); cpt++; return tmp; void Compteur::affichage() cout << cpt << endl;
7 QUESTION 07 - EXPRESSIONS, L/RVALUE 10 Code 17 Question 06 - Compteur : Opérateurs postfixe, infixe, interne, externe (+, +=) int main() Compteur a; a = a + 10; a.affichage(); ((a+10)++).affichage(); a.affichage(); ((++a+10)).affichage(); a.affichage(); // a = 10 + a; // pourquoi une erreur? a.affichage(); return 0;
7 QUESTION 07 - EXPRESSIONS, L/RVALUE 11 Code 18 Question 07 - Expressions, L/Rvalue #include <iostream> using namespace std; int main() int x = 9; x; 1; int y; y = int c = 10; x = 1; y = x = 1; int z; z = x * y = 10; if (x = 0) // si x vaut zéro on incrémente ++x; x = 0; if (++x!= 0) cout << x << endl; x = 0; if (x++!= 0) cout << x; return 0;