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 :

Problème de portée d'une variable déclarée dans un if


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 31
    Points : 18
    Points
    18
    Par défaut Problème de portée d'une variable déclarée dans un if
    Bonjour,
    j'ai une classe A qui a plusieurs constructeurs ; j'utilise un if pour savoir quel constructeur appeler pour construire l'objet a. Le problème est que a n'est plus reconnu en dehors du if.
    Comment faire ?

    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
     
    #include <iostream>
     
    class F1 {};
    class F2{};
    class A {
    public :
    int baba;
    A(F1 fic){baba=0;}
    A(F2 fic){baba=1;}
     
    };
     
    main()
    {
     
    int test;
    F1 f1;
    F2 f2;
     
    if (test==0)
         A a(f1);
    else if (test==1)
         A a(f2);
    else
         std::cerr << "test pas good" << std::endl;
     
    // probleme de portee :
    std::cout << "baba : " << a.baba << std::endl;
     
    }
    Le code précédent est simplifié au maximum, et génère une erreur à la compilation à cause de l'utilisation de a au-delà de sa portée.
    En utilisant les pointeurs, ça pourrait le faire :

    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
     
    #include <iostream>
     
    class F1 {};
    class F2{};
     
    class a_exception{};
     
    class A {
    public :
    int baba;
    A(F1 fic){baba=0;}
    A(F2 fic){baba=1;}
     
    };
     
    main()
    {
     
    int test=0;
    F1 f1;
    F2 f2;
    A *a;
     
    try {
    if (test==0)
         a=new A(f1);
    else if (test==1)
         a=new A(f2);
    else
         throw(a_exception());
    }
    catch(a_exception& e){
    std::cerr << "a non defini" << std::endl;
    }
     
    // plus de probleme
    std::cout << "baba : " << a->baba << std::endl;
     
    delete a;
     
    }
    mais j'ai une erreur de segmentation si test est différent de 0 ou 1 ?
    Quelqu'un a-t-il des conseils à me donner sur ce sujet ?
    Merci d'avance

  2. #2
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    En réassignant ?
    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
    #include <iostream>
     
    class F1 {};
    class F2{};
    class A {
    public :
    int baba;
    A(F1 fic){baba=0;}
    A(F2 fic){baba=1;}
     
    };
     
    main()
    {
     
    int test;
    F1 f1;
    F2 f2;
    A a;
     
    if (test==0)
        a = A(f1);
    else if (test==1)
         a = A(f2);
    else
         std::cerr << "test pas good" << std::endl;
     
    std::cout << "baba : " << a.baba << std::endl;
     
    }

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 31
    Points : 18
    Points
    18
    Par défaut
    Ca marche, à condition de définir le constructeur par défaut dans la classe A.
    Merci

    Tonio

  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
    La réassignation n'est pas forcément possible, et puis on a une variable non initialisée (pas logtemps, certes), ce qui est risque d'erreur... Je préfère généralement dans ces cas là passer par l'écriture :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    A a(test == 0 ?
          f1:
          f2);
    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
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 31
    Points : 18
    Points
    18
    Par défaut
    Je n'arrive pas à utiliser cette solution, mais je n'aime effectivement pas trainer des objets non initialisés. Cependant le code suivant ne compile pas ; et si j'ai trois constructeurs, il n'est pas utilisable...

    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
     
    #include <iostream>
     
    class F1 {};
    class F2{};
     
    class A {
    public :
    A(F1 fic){};
    A(F2 fic){};
    A(){};
     
    };
     
    main()
    {
     
    int test=0;
    F1 f1;
    F2 f2;
    A a(test==0 ? f1 : f2);
     
    }
    Est ce que la solution avec pointeurs n'est pas préférable et dans ce cas comment gérer l'exception pour ne pas faire de delete si le new A n a pas été réalisé ?

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    A a=A([..]) appelle le constructeur correspondant et non le constructeur par copie, donc tu peux l'utiliser avec ton opérateur ternaire :
    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
    #include <iostream>
     
    class F1 {};
    class F2{};
     
    class A {
    public :
    A(F1 fic){};
    A(F2 fic){};
    A(){};
     
    };
     
    int main()
    {
        int test=0;
        F1 f1;
        F2 f2;
        A a = (test==0 ? A(f1) : (test==1 ? A(f2) : A()));
     
        return 0;
    }
    Mais bon, au bout d'un moment ça peut devenir lourd. Si ton objet supporte la copie et si le compilo implémente la (N)RVO, tu peux passer par une fonction dédié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
    40
    41
    42
    #include <iostream>
     
    class F1 {};
    class F2{};
     
    class A {
    public :
    A(F1 fic){};
    A(F2 fic){};
    A(){};
     
    };
    template<class T>
    A make_a(T t_)
    {
        return A(t_);
    }
    A make_a(){return A();}
     
    A make_my_a(int test_)
    {
        switch(test_)
        {
            case 1:
            return make_a(F1());
            break;
            case 2:
            return make_a(F2());
            break;
            default:
            break;
        }
        return make_a();
    }
     
    int main()
    {
        int test=0;
        A a = make_my_a(test);
     
        return 0;
    }

  7. #7
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    +1 pour une fonction helper.
    Par contre 3DArchi.... pourquoi toute cette purée de template
    Quel est l'avantage par rapport au code classique ?
    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
     
    #include <iostream>
     
    class F1 {};
    class F2{};
     
    class A 
    {
    public:
       A(F1 fic){};
       A(F2 fic){};
       A(){};
    };
     
    A foo(int test)
    {
       F1 f1;
       F2 f2;
     
       switch(test)
       {
          case 1:
             return A(f1);
          case 2:
             return A(f2);
          default:
             return A();
       }
    }
     
    int main()
    {
       int test = 0;
       A a = foo(test);
    }

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Par contre 3DArchi.... pourquoi toute cette purée de template
    Pour toutes les fonctions make, une débordement d'enthousiasme. Pour les templates, la flemme d'écrire F1, F2, ... Bref pas de bonnes excuses.
    Histoire de me rattraper : Arzar, pourquoi déclarer f1 et f2 ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    A make_a(int test)
    { 
       switch(test)
       {
          case 1:
             return A(F1());
          case 2:
             return A(F2());
          default:
             return A();
       }
    }

  9. #9
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Arzar, pourquoi déclarer f1 et f2 ?
    Bah, copier-coller du code de tonio_a_588 qui déclare f1, f2, copier-coller de ton switch, et beaucoup de flemme

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 31
    Points : 18
    Points
    18
    Par défaut
    Merci les flemmards vos réponses m'ont été d'une bien grande aide

Discussions similaires

  1. [AS2] problème d'utilisation d'une variable number dans un calcul
    Par Mosler dans le forum ActionScript 1 & ActionScript 2
    Réponses: 2
    Dernier message: 12/06/2008, 22h44
  2. Réponses: 2
    Dernier message: 11/02/2008, 23h02
  3. Réponses: 2
    Dernier message: 24/10/2007, 18h00
  4. Réponses: 5
    Dernier message: 25/05/2007, 11h22
  5. accéder à une variable déclarée dans un autre fichier
    Par sg.forums dans le forum Servlets/JSP
    Réponses: 4
    Dernier message: 31/10/2006, 10h20

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