Bonjour.
J'essaie de d�finir une classe "safeUInt" (safe unsigned int) dont l'�ventail de valeurs serait le m�me que celui du type "unsigned int" mais auquel il serait impossible de passer une valeur n�gative, la conversion implicite �tant refus�e par le compilateur.

J'ai essay� d'utiliser le mot-cl� "explicit" dans le constructeur, mais cela semble ne servir � rien.

Voici le code :
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
 
// TypesSurs.cpp Définit une classe de nombres naturels, dont l'éventail de valeurs
// est le même que pour les unsigned int, mais dont le compilateur refuse l'instantiation à partir d'une valeur négative.
// On dirait que ça ne va pas.
// (le compilateur accepte une valeur négative et fait une conversion imlicite).
 
#include <iostream>
#include <climits>
#include <cstdlib> // Pour la fonction exit(0).
using std::cout;
using std::cin; // Je vais essayer de m'en servir pour empêcher la fenêtre de console de se
                // fermer immédiatement.
using std::endl;
 
class safeUInt
{
public:
  explicit safeUInt(unsigned int = 0); // constructeur de création. Le mot-clé "explicit" empêche le compilateur
// d'accepter autre chose qu'un "unsigned int". En fait, ça ne marche pas : Dev-C++ accepte avec un avertissement
// et Visual C++ 6 n'envoie même pas d'avertissement. 
  // On va expliciter le constructeur de copie, bien que ce ne soit pas nécessaire dans ce cas.
      safeUInt(const safeUInt& );
      void print() const; // const sert à ce que print ait accès aux objets déclarés comme constants.
  // On va expliciter l'opérateur surchargé d'affectation, bien que dans ce cas ce ne soit pas nécessaire. (Rappel : on ne peut surcharger = que par une fonction membre; quand un opérateur binaire est surchargé par une fonction membre, c'est l'opérande gauche qui est censé être désigné par this; Deitel, p. 528.)
      safeUInt& operator=(const safeUInt& );
   private:
      unsigned int sanssigne;
};
 
 
safeUInt::safeUInt(unsigned int i) // Constructeur de création. L'argument par défaut
// est indiqué dans le prototype.
{
// Si on passe une valeur négative pour i, le compilateur ne risque-t-il pas d'accepter
// et de faire une conversion implicite ? J'ai mis "explicit" dans le constructeur, mais
// on dirait que cela ne sert à rien.
  sanssigne = i;
}
  // On va expliciter le constructeur de copie, bien que ce ne soit pas nécessaire dans ce cas.
safeUInt::safeUInt(const safeUInt& n)
{ sanssigne = n.sanssigne;
}
 
  // On va expliciter l'opérateur surchargé d'affectation, bien que dans ce cas ce ne soit pas nécessaire.
safeUInt& safeUInt::operator=(const safeUInt& n)
{
  sanssigne = n.sanssigne;
  return *this;
}
void safeUInt::print() const
{ cout << sanssigne;
} // const sert à ce que la fonction membre print ait accès aux objets déclarés comme constants.
 
 
 
 
int main()
{
  int entreeBidon; // Recevra le cin qui sert à empêcher la fenêtre de console
                   // de se fermer immédiatement.
  cout << "le safeUInt(-1) vaut : " << endl;
  safeUInt(-1).print(); // Le compilateur l'accepte, avec un avertissement dans Dev-C++
// et sans avertissement dans Visual C++ 6..
  cout <<"\nTapez un chiffre pour fermer cette fenêtre." << endl; // Ceci n'est pas nécessaire si on lance
// le programme à partir de l'IDE de Visual C++ (cela fait même, dans ce cas, double emploi
// avec "Press any key to continue", mais cela me semble nécessaire si on le lance à partir de l'IDE de Dev-C++
  cin >> entreeBidon;
  return 0;
}
Quelqu'un voit-il ce qui cloche ?
Merci d'avance.