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

Langage C++ Discussion :

Surcharge du constructeur


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2012
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 72
    Par défaut Surcharge du constructeur
    Bonjour

    Voici un petit programme qui ne se comporte pas comme je le voudrais (CodeBlocks 13.12 sur Windows 7)

    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
     
    #include <iostream>
    #include <string>
     
    using namespace std;
     
    class EMC
    {
        unsigned  bof ;
     
        public:
     
        EMC(string s = "0"){cout<<endl<<"s = "<<s ;} ;
        EMC(unsigned n = 0){cout<<endl<<" n = "<<n ;} ;
        EMC(unsigned long long n = 0){cout<<endl<<" n = "<<n ;} ;
     
        ~EMC(){ ;} ;
    };
     
    int main()
    {
        EMC u("ok");
     //   EMC v = "pas ok" ;
        EMC w = (string)"ok" ;
     
        return 0;
    }
    Tel quel, il fonctionne. Mais voici le message reçu si on décommente la ligne.
    Nom : EMC.PNG
Affichages : 168
Taille : 24,0 Ko


    J'ai deux questions :
    1. la ligne commentée n'est-elle pas équivalente à la première ?
    2. pour lever l'ambiguïté pourquoi, sur les 3 constructeurs présents, le compilateur n'envisage-t-il pas le seul qui fonctionne ? La troisième ligne semble montrer qu'il le trouve si on l'aide un peu ...


    Merci d'avance

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 766
    Par défaut
    Parce que je pense que le compilateur voit 3 constructeurs par défaut (sans arguments)

    Tu croyais quoi? Qu'il allait faire un jet de dés

    Mets un explicit devant le constructeurs qui prend en paramètre un type string

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2012
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 72
    Par défaut
    Bonjour foetus

    Merci d'avoir répondu. Mais vu le niveau de mes connaissances, je vais avoir besoin d'un peu plus de détails.

    Citation Envoyé par foetus Voir le message
    Parce que je pense que le compilateur voit 3 constructeurs [...]
    Parfois, il semble n'en voir que 2 (question 2)

    [..] par défaut (sans arguments)
    J'ai retiré les valeurs par défaut, cela ne change rien.

    Tu croyais quoi? Qu'il allait faire un jet de dés
    Il semble bien que, dans certains cas, il arrive à faire son choix :
    • la ligne 22 montre qu'il se débrouille très bien, si on lui demande comme il faut.
    • la ligne 23 renvoie à ma question 1
    • la ligne 24 montre que si on convertit "ok" en string, ça marche : question "ok" n'est-il pas déjà une valeur de type string ?
    • Si on ajoute : string s = "ok" ; alors EMC x = s ; fonctionne.


    Mets un explicit devant le constructeurs qui prend en paramètre un type string
    Après avoir enlevé les valeurs par défaut, j'ai mis explicit devant le premier EMC (ligne 13).
    • la ligne 22 fonctionne toujours,
    • la ligne 23, toujours pas,
    • la ligne 23 et EMC x = s ; ne fonctionnent plus. Cela signifie qu'il y avait une conversion implicite utile avant, mais laquelle ?



    Je ne sais pas vraiment quoi faire : peux-tu modifier ce programme pour qu'il fonctionne?

    Merci encore

  4. #4
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 766
    Par défaut
    Désolé mais en lisant EMC v = "pas ok" ; j'ai compris EMC v pas ok

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Tu n'apelles pas les constructeurs mais les opérateur d'affectation. Le compilateur, intelligent, l'optimisera surement en appel au constructeur.
    "ok" n'est pas une string mais un const char* (ou peut-être const char[]), le fait est que std::string a un constructeur qui prend un const char* : ça s'apelle une conversion implicite
    1 seule et unique conversion implicite peut être faite lors de l'appel à une méthode.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre Expert

    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 : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    @Bousk: La syntaxe T t = u; ce n'est en aucun cas un appel à une affectation, c'est une syntaxe d'initialisation au même titre que T t(u); (et d'autre en C++11).

    @foetus: La question c'est pourquoi EMC u("ok"); fonctionne et pas EMC v = "pas ok";.

    @OP: En général on considère que ces deux syntaxes sont strictement équivalentes (EMC u("ok"); et EMC v = "pas ok";). En réalité ce n'est pas le cas, la première se nomme "initialisation direct" et la seconde "initialisation par copie", les mécanismes sont un peu différents :
    • Pour la première il regarde les différents constructeur, et il essaie de "faire correspondre" le type de "ok" au type de ton argument (std::string donc).
    • Pour la seconde, il essaie directement de "faire correspondre" le type de "pas ok" au type de ta classe (EMC donc).


    Reste à savoir ce que veut dire "faire correspondre", ici ça veut dire "une séquence de conversion permettant d'aller d'un type à un autre", une conversion pouvant être définie de différentes manières, dont une est une constructeur (non explicite). D'autre part certaines règles sont imposées à ces séquences, entre autre (et pour faire simple) une seule conversion définie par un constructeur (non explicite) dans la séquence (ce que disait Bousk)

    Dans ton cas, on veut aller de const char[N] à std::string ou EMC, on a :
    • Une conversion de const char[N] à const char* (c'est une conversion "naturelle")
    • Une conversion de const char* à std::string (définit par constructeur)
    • Une conversion de std::string à EMC (définit par constructeur)

    Donc dans ton premier appel on arrive à "faire correspondre" sans problème le type de "ok" à std::string, par contre dans le second on ne peut pas "faire correspondre" le type de "pas ok" à EMC car ceci impliquerait deux conversions définies par constructeur (non explicite).

    Code minimal illustrant le problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include<string>
     
    struct A
    { A(std::string){} };
     
    int main()
    {
    	A a("a");	//Compile
    	A b = "b";	//Ne compile pas
    }

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

Discussions similaires

  1. Surcharger un constructeur de classe
    Par pdgnr dans le forum C++Builder
    Réponses: 5
    Dernier message: 09/11/2006, 10h17
  2. [POO] Surcharge de constructeur
    Par loganblack dans le forum Langage
    Réponses: 4
    Dernier message: 17/05/2006, 12h26
  3. Réponses: 19
    Dernier message: 19/04/2006, 10h16
  4. [POO] surcharger le constructeur
    Par wdionysos dans le forum Langage
    Réponses: 9
    Dernier message: 22/03/2006, 15h42
  5. Surcharge de constructeur???
    Par Sunsawe dans le forum Général Python
    Réponses: 3
    Dernier message: 14/03/2006, 17h26

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