Barême et notation

Problème

Exercice 1: 6 points

Il fallait donner 6 réponses, 1 point par réponse.
#include <iostream.h>

struct c {
      int i;

      c(int)               { i = 5;  }
      c(float)             { cout << 17 << ' '; }
      ~c()                 { cout << 43 << ' '; }
      void operator=(int)  { i = 7;  }
      int m()              { return 11; }

};

struct d: public c {
      d(): c('a')     { }
      d(int): c(1.0f) { cout << 19 << ' '; }
      ~d()            { cout << 41 << ' '; }
      int m()         { return 13; }

      int n() const   { return 31; }
      int n()         { return 37; }

};

ostream &operator<<(ostream &s, const d&)
{
      s << 23 << ' ';
}

main()
{
      c x(1);                       
      cout << "a: " << x.i << endl;

Réponse: a: 5

Tout le monde a répondu correctement.


      c y = 2;                      
      cout << "b: " << y.i << endl;
Réponse: b: 5

Il fallait ici reconnaître qu'il s'agit d'un constructeur, et non d'une affectation.


      d z;
      c &r = z;
      cout << "c: " << r.m() << endl;
Réponse: c: 11

La méthode n'est pas virtuelle dans c, ici on a une référence sur c, c'est donc cette méthode (celle de c) qui joue.


      cout << "d: " << d(1) << endl;
Réponse: d: 17 19 23 41 43

Il ne fallait pas oublier l'appel à <<. Les puristes auraient pu faire remarquer que, comme il n'y a pas de return dans l'opérateur, le comportement est indéfini (j'ai accepté cette réponse). Il ne fallait pas oublier les destructeurs (ceux qui n'ont mis que 17 19 23 avaient néanmoins 1/2 point). Je n'ai pas tenu compte de l'ordre des destructeurs.


      cout << "e: " << z.n() << endl;
Réponse: e: 37

Un point délicat de l'exercice. La bonne justification est que le profil de l'opérateur est operator<<(ostream &, int);; il aurait fallu que ce soit const int pour que l'autre option soit prise. Le fait que t et const t soient des types distincts est un des éléments gênants de C++.

Et il ne fallait pas oublier: 41 43 43 43, les destructeurs de d, y, et x, respectivement. J'étais tellement content de les voir que j'ai donné le point même à ceux qui ne les ont pas mis dans l'ordre.

      
}

Exercice 2: 4 points

On partait avec un capital de 4 points, et on perdait 1/2 point par réponse fausse.

  1. char *p;
  2. const char *q;
  3. char &r;
Celle-ci est fausse: une référence doit toujours être initialisée.

  4. char t[10];
  5. q = p;
Celle-ci est correcte: on affecte la valeur d'un pointeur au travers duquel on peut modifier la mémoire à un pointeur au travers duquel on ne peut pas le faire, mais ça ne pose pas de problème particulier (i.e. les types sont préservés).

  6. r = p;
La ligne 6 est fausse: on ne peut affecter un pointeur à un caractère. Quelques-uns ont indiqués que la ligne était fausse parce que la déclaration de r était fausse, une réponse acceptée.

  7. char &s = *p;
  8. p = &s;
  9. s = p;
Faux: on ne peut affecter un pointeur à un caractère.

 10. p = s;
Faux: on ne peut davantage affecter un caractère à un pointeur.

 11. s = *p;
 12. *p = s;
 13. t = p;
Faux: un pointeur qui dénote le premier élément d'un tableau ne peut être modifié.

 14. p = t;
 15. *t = *p;
Cette dernière ligne est correcte, elle correspond à l'affectation de la première case du tableau (puisque le nom d'un tableau est un pointeur qui dénote l'adresse du tableau, c'est à dire de la première case.
Christophe Tronche, ch@tronche.com