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 :

Résolution de liens


Sujet :

C++

  1. #1
    Invité
    Invité(e)
    Par défaut Résolution de liens
    Hoï ! En ce moment j'étudie l'héritage, et donc avec ça, le polymorphisme.
    Seulement voilà, je n'arrive pas à faire de résolution de lien, à chaque fois c'est la méthode de la classe mère qui est appelée. Pourtant cette fonction est bien virtuelle et j'utilise un pointeur.
    Voici le code :
    test.h :
    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
    51
    52
    53
    54
    55
    56
    #ifndef TEST_H_INCLUDED
    #define TEST_H_INCLUDED
     
    #include <iostream>
     
     
    class Vehicule
    {
    public:
        int getAnneeConstr() const;
        virtual void afficher() const;
        int getRoues() const;
        Vehicule();
        Vehicule(int a);
        Vehicule(int a,int b);
        virtual ~Vehicule();
    protected:
        int m_prix;
        int m_anneeDeConstruction;
    };
    class Voiture:public Vehicule
    {
    public:
        void afficher() const;
        int roues() const;
        Voiture();
        Voiture(int a,int b,int c);
    private:
        int m_portes;
    };
    class Moto:public Vehicule
    {
    public:
        void afficher() const;
        int roues() const;
        Moto();
        Moto(double a,int b,int c);
    private:
        double m_vitesseMax;
    };
    class Camion:public Vehicule
    {
    public:
        void afficher() const;
        int roues() const;
        Camion();
        Camion(double a,int b,int c);
    private :
        double m_poidsMax;
    };
     
     
    void afficheVehicule(Vehicule const& a);
     
     
    #endif // TEST_H_INCLUDED
    test.cpp :
    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
    51
    52
    53
    54
    #include <iostream>
    #include "test.h"
     
    using namespace std;
     
    void afficheVehicule(Vehicule const& a)
    {
        a.afficher();
    }
     
    Vehicule::Vehicule():m_prix(5000),m_anneeDeConstruction(2000){}
    Vehicule::Vehicule(int a,int b):m_prix(a),m_anneeDeConstruction(b){}
    Vehicule::~Vehicule(){};
    void Vehicule::afficher() const
    {
        cout<<"Ceci est un vehicule coutant "<<m_prix<<" euros."<<endl;
    }
    int Vehicule::getAnneeConstr() const
    {
        return m_anneeDeConstruction;
    }
     
    Voiture::Voiture():m_portes(2){}
    Voiture::Voiture(int a,int b,int c):Vehicule(b,c),m_portes(a){}
    void Voiture::afficher() const
    {
        cout<<"Ceci est une voiture coutant "<<m_prix<<" euros et ayant "<<m_portes<<" portes."<<endl;
    }
    int Voiture::roues() const
    {
        return 4;
    }
     
    Moto::Moto():m_vitesseMax(100){}
    Moto::Moto(double a,int b,int c):Vehicule(b,c),m_vitesseMax(a){}
    void Moto::afficher() const
    {
        cout<<"Ceci est une moto coutant "<<m_prix<<" euros et montant jusqu'a "<<m_vitesseMax<<" km/h."<<endl;
    }
    int Moto::roues() const
    {
        return 2;
    }
     
    Camion::Camion():m_poidsMax(38){}
    Camion::Camion(double a,int b,int c):Vehicule(b,c),m_poidsMax(a){}
    void Camion::afficher() const
    {
        cout<<"Ceci est un camion coutant "<<m_prix<<" euros et pouvant porter jusqu'a "<<m_poidsMax<<" tonnes."<<endl;
    }
    int Camion::roues() const
    {
        return 10;
    }
    main.cpp :
    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
    51
    52
    53
    #include <iostream>
    #include <vector>
    #include "test.h"
     
    using namespace std;
     
     
    int main()
    {
        string reponse;
        double b;
        int c,d,answer;
        Vehicule* ptr(NULL);
        vector<Vehicule>garage(0);
        cout<<"Ajouter un vehicule ?"<<endl;
        cin>>reponse;
        while(reponse=="oui" || reponse=="OUI" || reponse=="Oui")
        {
            cout<<"1:Voiture ; 2:Moto ; 3:Camion"<<endl;
            cin>>answer;
            switch(answer)
            {
            case 1:
                cout<<"nbrPortes prix anneeDeConstruction"<<endl;
                cin>>b>>c>>d;
                garage.push_back(Voiture(b,c,d));
                break;
            case 2:
                cout<<"vitesseMax prix anneeDeConstruction"<<endl;
                cin>>b>>c>>d;
                garage.push_back(Moto(b,c,d));
                break;
            case 3:
                cout<<"poidsMax prix anneeDeConstruction"<<endl;
                cin>>b>>c>>d;
                garage.push_back(Camion(b,c,d));
                break;
            default:
                cout<<"prix anneeDeConstruction"<<endl;
                cin>>c>>d;
                garage.push_back(Vehicule(c,d));
                break;
            }
            for(int i(0);i<(int)garage.size();i++)
            {
                ptr=&garage[i];
                ptr->afficher();
            }
            cout<<"Ajouter un vehicule ?"<<endl;
            cin>>reponse;
        }
        return 0;
    }
    Est-ce que c'est le fait d'avoir utilisé un tableau qui pose problème ? Ou alors j'utilise mal le pointeur ?
    À noter que j'ai aussi essayé en utilisant une référence avec cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void afficheVehicule(Vehicule const& a)
    {
        a.afficher();
    }
    Sans plus de résultat. À chaque fois la boucle l.44-48 de main.cpp m'affiche tout comme si le tableau ne contenait que des Vehicule.

    Merci d'avance pour votre aide !

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    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 772
    Par défaut
    Déjà utilise un do while pour éviter de répéter de demander d'ajouter un véhicule.
    Édit: le do while n'est peut-être pas une bonne idée

    Et ensuite, tu as oublié que pour fonctionner, le polymorphisme a besoin du late binding.
    Le lien qui va bien: Late binding
    Tu crées un vecteur d'objets de type Vehicule (garage) et donc le type est figé à la compilation.

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    En raccourci, le polymorphisme ne fonctionne qu'avec des pointeurs ou des références.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Ok, je suis pas sûr de comprendre ce qu'est le late binding, donc je crois que je vais plutôt faire un vecteur de pointeurs. Ça fonctionnerait ?

  5. #5
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    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 772
    Par défaut
    En gros pour simplifier, le late binding c'est la table des méthodes virtuelles ("v-table")

    Lorsque tu codes ptr->afficher(); et comme ton vecteur contient que des objets de type Vehicule, ce sera juste un appel à la méthode afficher de la classe Vehicule.

    Mais si dans ton vecteur tu mets des pointeurs (ou des références mais il faut voir le cas) le compilateur va passer par la "v-table"
    Objet -> v-table -> afficher

    Et fais attention au slicing de tes objets:

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    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 153
    Billets dans le blog
    4
    Par défaut
    Le problème c'est que non tu n'utilises pas de pointeur ni référence... donc pour le polymorphisme c'est foutu.

    Tu déclares un vector<Vehicule>, qui est un magnifique vector de Vehicule. Je ne vois là ni pointeur ni référence, et pour cause : il n'y en a pas !
    Chaque fois que tu ajoutes un élément, tu ajoutes un Véhicule. Que le véhicule ajouté soit copié depuis un Camion ne change pas le fait que tu ajoutes un simple Vehicule. Ton conteneur ne peut contenir que des Vehicule, et c'est tout ce qu'il contient. Tout au plus la partie Vehicule de ton camion utilisé pour la copie, mais certainement pas de Camion.

    edit: je préfère parler de typage dynamique, il est inutile de l'embrouiller avec les v-table etc. qui sont en pratiques (quasi) totalement transparentes pour le programmeur.
    Un pointeur a un typage statique, son type, et un typage dynamique, son type réel caché derrière.
    Le polymorphisme fait appel à ce type dynamique, mais nécessite un pointeur ou référence.
    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.

  7. #7
    Invité
    Invité(e)
    Par défaut
    C'est donc bien le tableau qui posait problème.
    Merci à tous pour vos explications !

    EDIT : ça fonctionne en faisant un vecteur de pointeurs, comme prévu. Merci encore !

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 28/04/2014, 21h08
  2. [FLASH 5] Comment créer un lien hypertexte
    Par ajit dans le forum Flash
    Réponses: 4
    Dernier message: 30/03/2006, 12h26
  3. recuperer la résolution de l'écran
    Par florent dans le forum C++Builder
    Réponses: 11
    Dernier message: 07/06/2002, 15h01
  4. [Kylix] Création d'un fichier lien
    Par DrQ dans le forum EDI
    Réponses: 2
    Dernier message: 14/05/2002, 21h30
  5. Tutoriels et liens pour le Borland Database Engine
    Par Community Management dans le forum Paradox
    Réponses: 0
    Dernier message: 25/03/2002, 10h23

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