IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Le mot-clé "explicit"


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 107
    Par défaut Le mot-clé "explicit"
    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.

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Le mot-clé explicit n'empêchera pas le compilateur d'accepter autre chose qu'un unsigned int, ça l'empêchera juste de convertir implicitement un unsigned int en safeUInt. Tout ce qui est convertible implicitement en unsigned int sera par contre valide.

    Le plus simple serait de faire le test à l'exécution : jeter une exception si la valeur est négative.
    Parce que ta classe devrait tout de même pouvoir recevoir des variables de types signés positives.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 107
    Par défaut
    Citation Envoyé par Laurent Gomila
    Le mot-clé explicit n'empêchera pas le compilateur d'accepter autre chose qu'un unsigned int, ça l'empêchera juste de convertir implicitement un unsigned int en safeUInt. Tout ce qui est convertible implicitement en unsigned int sera par contre valide.

    Le plus simple serait de faire le test à l'exécution : jeter une exception si la valeur est négative.
    Parce que ta classe devrait tout de même pouvoir recevoir des variables de types signés positives.
    Merci.
    N'y a-t-il vraiment pas moyen d'obtenir un contrôle à la compilation ? Ce serait beaucoup mieux...

    P.S. Dans mon esprit, la classe ne recevrait des valeurs signées positives qu'après une conversion explicite, qui serait précédée d'une vérification du signe. En fait, j'aimerais remplacer tous les types numériques par des types "sûrs" et définir les opérations arithmétiques ad hoc sur ces types sûrs. Les opérations arithmétiques qui sortiraient des limites ne seraient détectées qu'à l'exécution (je ne vois pas comment on pourrait faire autrement) mais je trouve dommage que la conversion implicite de signed int vers unsigned int (pas vraiment intéressante...) empêche le contrôle de la construction à la compilation.
    M.

  4. #4
    Rédacteur
    Avatar de bafman
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    2 574
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2003
    Messages : 2 574
    Par défaut
    une solution pourrait être de definir des conscteur prennant en paramètre les type que tu veut verifier mais sans implementer le constructeur, comme ca, si on appel le constructeur sans passer par une verification avant, le compilo va geuler
    * Il est infiniment plus simple de faire rapidement un code qui marche que de faire un code rapide qui marche
    * pour faciliter les recherches, n'oubliez pas de voter pour les réponses pertinentes
    Mes articles

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Pas sûr que dans ce cas le compilo n'utilise pas la conversion implicite vers un type non signé pour appeler un autre constructeur qui est bien défini.

+ Répondre à la discussion
Cette discussion est résolue.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo