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++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 31
    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 Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    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 averti
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 31
    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 : 50
    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
    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 averti
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 31
    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
    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;
    }

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, 21h44
  2. Réponses: 2
    Dernier message: 11/02/2008, 22h02
  3. Réponses: 2
    Dernier message: 24/10/2007, 17h00
  4. Réponses: 5
    Dernier message: 25/05/2007, 10h22
  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, 09h20

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