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 :

Surdéfinition de l'opérateur de cast (void *)


Sujet :

C++

  1. #1
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut Surdéfinition de l'opérateur de cast (void *)
    Bonjour,

    J'étais en train d'étudier le mécanisme qui permet de réaliser l'opération suivante avec un flot tel que, par exemple, cin:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    using namespace std;
    // ...
    char c;
    // ...
    // Recopie le flot cin sur le flot cout
    while ( cin.get(c) ){
        cout.put(c);
    }
    Le fonctionnement du morceau de code ci-dessus passe par la surchage de l'opérateur de cast (void*). Je me suis donc construit un petit exemple afin d'étudier ce mécanisme. Il s'agit d'une classe qui représente un index de boucle. 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
    #include <iostream>
    /*
     * Représente un index de boucle.
     *
     * Aucun autre intérêt que celui d'étudier la surchage de l'opérateur
     * (void*) comme c'est le cas pour les flots d'entrée/sortie
     */
    class IndexBoucle {
     
        int i; // Valeur de l'entier
        int max; // i doit rester inférieur à max
     
        public:
        // Constructeur de la classe
        IndexBoucle(int limite)
        {
            if ( i<limite )
            {
                i = 0;
                max = limite;
            }
        }
        // Accesseur permettant d'obtenir i
        int getIndex()
        {
            return i;
        }
        // Surcharge de l'opérateur de cast (void*)
        operator void*()
        {
            return (++i<max) ? this : NULL;
        }
    };
     
     
     
    int main()
    {
        IndexBoucle i(10);
        /* La valeur de l'index est incémentée au sein de 
         * IndexBoucle::operator void*() qui renvoit NULL
         * lorsque l'index vaut 10.
         */
        while (i)
        {
            std::cout << "Iteration " << i.getIndex() << std::endl;
        }
     
        return 0;
    }
    Tout fonctionne parfaitement, mais je voudrais savoir à quel niveau intervient le cast (void *) dans la construction:

    Y a-t'il conversion implicite de i (ici un objet de type IndexBoucle, mais cela peut également être un flot dont on désire tester le status d'erreur) en un pointeur générique? Est-ce un point définit par la norme ou est-ce que cela dépend de l'implémentation?

    Merci d'avance pour avis

    Meilleures salutations

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Le fonctionnement du morceau de code ci-dessus passe par la surchage de l'opérateur de cast (void*).
    T'as tout faux.
    Ce sont des opérateurs de conversions (la conversion est implicite, à l'inverse du cast). Et ce n'est pas nécessairement vers void*, mais vers le type que tu veux.
    C'est en général à éviter pusique les constructeurs non explicites proposent un mécanisme similaire dans l'autre sens.

    Dans ton cas, tu ferais mieux de fournir un opérateur de conversion vers bool.
    Boost ftw

  3. #3
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Toutes ces convertions ont divers défaut dans la famille des conversions implicites non désirées.
    Dernièrement, je suis tombé sur une conversion vers pointeur sur variable membre qui m'a bien plue.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct S {
        struct boolean {int i;};
        operator int boolean::* () const
        { return (expr) ? &boolean::i : 0 ; }
    };
    Les défauts étant :
    - les très vieux compilos -- même mon vieux SunCC du boulot semble supporter
    - pas d'algèbre de boole immédiate -> if (s1 && s2)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    boost en utilise une variante pour ses shared_ptr, avec un pointeur sur fonction membre. On peut y voir une description ici http://www.artima.com/cppsource/safebool.html

    Le seul problème, c'est que ça ne marche pas bien avec des compilateurs récents et répendus que je ne citerai pas, qui possèdent un mode C++/CLI et qui ne définissent pas un pointeur nul de fonction de la même manière dans le code C++ et le code managé, et ne font pas la conversion au passage...

    Et en plus, quand on leur fait un bug report, ces gens se permettent de le fermer plusieurs mois plus tard en disant que c'est un problème dans la lib externe, alors que c'est un problème chez eux, et il n'y a pas moyen de le réouvrir...

    Je n'ai pas fait le test pour savoir si ça passe avec des pointeurs sur donnée membre au lieu de pointeur sur fonction membre.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    C'est en essayant de savoir quel opérateur était surdéfinit dans istream ou une de ses classes de bases afin de supporter un mécanisme tel que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char c;
    while (cin.get(c)){
        // ...
    }
    que je me suis rendu compte que dans le cas de mon implémentation, c'est operator void*() qui est surchargé, et ma question est que je ne comprend pas en quoi cette surchage supporte le mécanisme ci-dessus. En d'autres terme, par quelle logique la construction while (cin.get(c)) fait-elle applel à operator void*()?
    Citation Envoyé par loufoque
    Dans ton cas, tu ferais mieux de fournir un opérateur de conversion vers bool.
    L'exemple présenté plus haut était un exemple dont je me suis servi pour essayer de comprendre ce qui se passe avec un flot entrant. Je ne comprend pas où a lieu la conversion implicite dans cette construction?Tu as raison, surcharger la conversion vers le type bool serait une approche plus compréhensible.

    Merci pour vos réponses

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

Discussions similaires

  1. Cast void* - Objet C++
    Par LaMainSurLeKatana dans le forum C++
    Réponses: 5
    Dernier message: 24/08/2010, 13h09
  2. opérateur de cast bool.
    Par 3DArchi dans le forum Boost
    Réponses: 7
    Dernier message: 09/12/2008, 10h29
  3. cast (void*) -> (char)
    Par nicodn02 dans le forum C
    Réponses: 10
    Dernier message: 14/04/2008, 10h02
  4. String - Surdéfinition de l'opérateur(+)
    Par slashbrus dans le forum Langage
    Réponses: 18
    Dernier message: 09/01/2008, 08h14
  5. Réponses: 1
    Dernier message: 03/04/2006, 23h15

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