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 :

Les différences entre les cast c++ et c


Sujet :

C++

  1. #1
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut Les différences entre les cast c++ et c
    Bonjour, cela fait maintenant quelques mois que je fais du c++ et je n'ai toujours pas utilisé les cast du c++. Ma question sera donc : Quel est l'avantage d'un cast à la c++ (par rapport aux casts du c) mis à part l'erreur bad_cast qui peut être lancée.

    De plus, dans cette situation (C'est une situation simplifiée):

    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
    #include <iostream>
    #include <vector>
     
    class Polygone
    {
        protected :
            int nb_cote;
        public :
            Polygone(int nb){nb_cote=nb;}
            virtual void show(){std::cout<<"\n"<<nb_cote;}
    };
     
    class Carre : public Polygone
    {
        private :
            int size;
        public :
            Carre(int s): Polygone(4){size=s;}
            void show(){std::cout<<"\n"<<nb_cote<<" "<<size;}
            void set_length(int len){size=len;}
    };
     
     
    int main()
    {
        Carre car(20);
        Polygone pol(3);
        std::vector<Polygone*>mes_objets;
        mes_objets.push_back(&car);
        mes_objets.push_back(&pol);
     
        mes_objets[0]->show();
        mes_objets[0]->set_length(40);//Erreur de compilation
        Carre*pt=(Carre*)mes_objets[0];//Ne pose pas de Problèmes (cast à la C) peut etre remplacer par dynamic_cast sans probleme
        pt->set_length(40);
        mes_objets[1]->show();
     
     
    }

    Quel serait l'avantage d'un dynamic cast ? Le cast à la C sera t-il résolut à la compilation ? Si oui, sera t-il plus rapide ?

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    En C, il n'y qu'un seul type de cast, c'est un reinterpret_cast.

    Donc tous les autres types de cast ne sont pas utilisables en C.

    Les casts, C ou C++, doivent être évité au maximum.

    L'exemple donné est un exemple parfait du polymorphisme, enlevez tous les casts et vous verrez qu'il marche très bien sans.

    La syntaxe des casts C++ est plus facile à distingue dans du code. C'est très important quand on cherche à les enlever. Ce qui arrivera tôt ou tard.

    Comme ne nom l'indique, le dynamic cast se fera à l'exécution.
    Si vous voulez avoir un cast résolu à la compilation, c'est un static cast.

    Si vous maitrisez les différences entre les différents types de cast, vous verrez aucun n'est interchangeable avec un autre.

  3. #3
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    Bacelar, tu as tout a fait raison, mon l'exemple que j'avais mis ci-dessus ne correspondait pas à faire ce que je voulais montrer. Tu as du commercer à écrire ta réponse pendant que j'éditais et donc tu n'as pas vu l'actualisation.
    Il me semble, que le cast du C fait tous les casts du c++ en un seul. Quelqu'un pourrait-il le confirmer ou me contredire ?

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Non.

    Cast C = reinterpret_cast C++

  5. #5
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    Dans ce cas, quelqu'un utiliserait-il un reinterpret_cast et non un dynamic_cast dans mon exemple ?

  6. #6
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    Après quelques tests, je me rend vite compte que le cast du C fait aussi const_cast et static_cast :

    exemple (const cast)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <iostream>
    #include <vector>
    #include <string>
     
    int main()
    {
        std::string test("test");
        const char*p=test.c_str();
        char*pt=(char*)p;
        pt[0]='T';
        std::cout<<pt;
    }
    Ceci affiche Test et non test.

    Et le C a toujours fait les static_cast.

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Faites la même expérience avec reinterpret_cast à la place du cast C et vous aurez le même résultat.

    C'est à croire que vous ne savez pas à quoi sert un cast.

    dynamic_cast -> demande au compilateur d'ajouter du code qui permettra à l'exécution de faire pointer la référence ou le pointeur d'objet d'un type A vers un type B. Le compilateur vérifiera donc qu'il est à même de générer le code, donc que A et B sont lié par de l'héritage, que le RTTI est applicable etc.. en un mots, pouvoir tester le type de l'objet en B et convertir (via de l'arithmétique de pointeur) de A vers B

    static_cast -> demande au compilateur de générer du code qui, à la compilation, convertira un objet A en B (via de l'arithmétique de pointeur).

    const_cast -> demande au compilateur de passer outre le caractère const de la variable mais n'ajoute pas ni ne génère de code supplémentaire.

    reinterpret_cast -> demande au compilateur de faire confiance au programmeur mais n'ajoute pas ni ne génère de code supplémentaire.

    Dans votre exemple, le code de conversion d'un objet A en B est vide, donc tous les casts qui n'ont rien à voir entre eux, donnent le même résultat.

    Faites un exemple avec une classe A, une classe B et une classe C qui dérive de A et de B et faite les différents casts, vous verrez que le résultat est totalement différent.

  8. #8
    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
    cast C != reinterpret_cast
    Cela dépend du contexte.

    http://www.developpez.net/forums/d92...p/#post5210670
    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...

  9. #9
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Un cast à la C peut être tout les autres type de cast (sauf dynamic_cast). Quand le compilateur voit un C-cast, il effectue le premier cast qu'il peut parmi (dans l'ordre) :
    - const_cast
    - static_cast
    - static_cast suivit de const_cast
    - reinterpret_cast
    - reinterpret_cast suivit de const_cast
    A quelques exceptions près (réalise un static_cast même si la base est innaccesible, et une règle spécifique si les 2 types sont incomplet). Norme section 5.4.

  10. #10
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    Donc le reinterpret_cast permet tout (car le compilateur fait confiance au programmeur) ? Tous les exemples que j'ai vu de dynamic_cast sont remplaçables par un reinterpret_cast tant que l'on ne se trompe pas sur le typeid.
    Ai-je bien compris ? Donc, pourquoi ne pas toujours utiliser un reinterpret_cast (et faire un typeid avant au cas ou)? Quels sont les avantages des autres cast ?

    [EDIT] Les deux derniers posts ayant étés écrits pendant que j'écrivais le mien, je ne les ai pas prit en compte.

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Elle est où la vérification de type à l'exécution dans un reinterpret_cast ?
    Il est où le code de conversion d'un type en un autre dans un reinterpret_cast ? Si A et B ne sont pas triviaux, ce code il ne sera pas trivial.

    P.S.: Flop90, vous avez tout à fait raison sur un compilateur C++ configuré sur des fichiers source C++, mais les cast C non aucun intérêt dans ce cas extrêmement ambigüe pour de sombres histoire des compatibilité historique.
    Il n'y a aucun intérêt au cast C et il faut connaître la différence entre les différents cast C++ qui ne sont pas interchangeable.

  12. #12
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    Merci beaucoup Luc Hermitte pour ce lien et Flob90 pour les priorité, cela m'a tout éclaircit.
    Juste pour vérifier, un cast A la C peut être utilisé pour tout type de conversion sauf si on veut pouvoir avoir l'exception bad_cast.

    De plus, Imaginons une classe A et B n'ayant aucun lien et n'ayant pas la même taille . Peut t-on convertir un A en B (peut importe le cast)?

    Dernière chose, pourquoi ce code ne compile pas (Erreur au reinterpret cast)?

    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
     
     
    #include <iostream>
    #include <vector>
    #include <string>
     
    class A
    {
        private :
            int nb;
        public :
            A(int n){nb=n;}
            void set_int(int n){nb=n;}
            int get_int(){return nb;}
    };
     
    class B
    {
        private :
            char one;
            char two;
            char three;
            char four;
        public :
            B(char n){one=n;}
            B(B& two){one=two.one;}
            void set_int(char n){one=n;}//Pour les noms de fonctions, j'ai juste copier coller
            char get_int(){return one;}
    };
     
     
    int main()
    {
        std::cout <<sizeof(A)<<" "<<sizeof(B);
        A testa(10);
        B testb(reinterpret_cast<B>(testa));
    }

    Les sizeof m'indiquent bien 4 et 4. Pourquoi ce cast m'est-il refusé ? alors que si je passe par les pointeurs, le cast marche :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main()
    {
        std::cout <<sizeof(A)<<" "<<sizeof(B);
        A testa(10);
        B* testb=(B*)(&testa);
    }
    De plus, dans ce dernier exemple, quel cast c++ ce cast C utilise t-il ? (static_cast ?)

  13. #13
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Citation Envoyé par bacelar Voir le message
    P.S.: Flop90, vous avez tout à fait raison sur un compilateur C++ configuré sur des fichiers source C++, mais les cast C non aucun intérêt dans ce cas extrêmement ambigüe pour de sombres histoire des compatibilité historique.
    Il n'y a aucun intérêt au cast C et il faut connaître la différence entre les différents cast C++ qui ne sont pas interchangeable.
    Je contre-disant juste votre affirmation Cast C = reinterpret_cast, comme Luc l'a fait pendant que j'écrivais. Après je suis d'accord pour bannir les cast C et préférer les cast C++ dans la grande majorité des cas.

    @OP: reinterpret_cast fonctionne sur des pointeur, des références et des types entier, pas sur n'importe quoi. reinterpret_cast<B&> marchera.
    Pour le dernier exemple je dirais reinterpret_cast. Et pas besoin de tester les tailles des types pour que le reinterpret_cast soit valide.

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par NoIdea Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main()
    {
        std::cout <<sizeof(A)<<" "<<sizeof(B);
        A testa(10);
        B* testb=(B*)(&testa);
    }
    De plus, dans ce dernier exemple, quel cast c++ ce cast C utilise t-il ? (static_cast ?)
    Clairement un reinterpret_cast<>.

    Avec le temps, je suis devenu un fanatique de la const-correctness, c'est pourquoi je n'utilise plus jamais les casts C avec des pointeurs: Le cast C peut faire un const_cast et c'est très difficile à repérer.
    (faire attention aussi, certaines fonctions C ne sont pas const-correctes, notamment strtol() et la famille strchr())
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 03/03/2009, 09h01
  2. [EJB] Différence entre les EJB et les JavaBeans
    Par cool dans le forum Java EE
    Réponses: 6
    Dernier message: 22/05/2008, 20h24
  3. Différence entre les fichiers et les files
    Par amine6441 dans le forum Langage
    Réponses: 1
    Dernier message: 14/01/2007, 09h59
  4. [C#] Diffèrence entre les structures et les classes
    Par Kr00pS dans le forum Windows Forms
    Réponses: 2
    Dernier message: 31/08/2006, 12h42

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