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 :

Méthode virtuelle pure undefined


Sujet :

C++

  1. #1
    Membre actif

    Inscrit en
    Août 2005
    Messages
    401
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 401
    Points : 228
    Points
    228
    Par défaut Méthode virtuelle pure undefined
    Bonsoir à tous,

    J'ai besoin d'une petite aide je viens de débuter mon apprentissage en C++ est c'est pas simple. J'essaye de faire de l'héritage avec es méthodes virtuelles pures. Toujours est-il que je me lance et qu'il y a une erreur que je ne comprends pas.

    Main.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
     
    #ifndef MAIN_H_
    #define MAIN_H_
     
    #include <iostream>
    #include "Vehicule.h"
    #include "Voiture.h"
     
    using namespace std;
     
    class Main {
    };
     
    #endif
    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
     
    #include "Main.h"
     
    int main() {
    	cout << "Gestion d'une flotte de vehicules" << endl;
     
    	Voiture* v;
    	v = new Voiture;
    	v->test();
    	//v->addPassenger();
     
    	return 0;
    }
    Vehicule.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
     
    #ifndef VEHICULE_H_
    #define VEHICULE_H_
     
    #include <iostream>
     
    using namespace std;
     
    class Vehicule {
    	int passager;
     
    public:
    	virtual void addPassenger() = 0;
    };
     
    #endif
    Voiture.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
     
    #ifndef VOITURE_H_
    #define VOITURE_H_
     
    #include <iostream>
    #include "Vehicule.h"
     
    using namespace std;
     
    class Voiture: public Vehicule {
    public:
    	Voiture();
    	virtual ~Voiture();
     
    	void test();
    	void addPassenger();
    };
     
    #endif
    Voiture.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
     
    #include "Voiture.h"
     
    Voiture::Voiture() {
    	cout << " voiture" << endl;
    }
     
    Voiture::~Voiture() {
    	// TODO Auto-generated destructor stub
    }
     
    void test() {
    	cout << "TEST OK" << endl;
    }
    /*
    void addPassenger() {
    	cout << "Ajout de passagers" << endl;
    }
    */
    En exécutant ce programme j'obtiens ceci :
    Building target: TESTCPP
    Invoking: GCC C++ Linker
    g++ -o "TESTCPP" ./src/Main.o ./src/Voiture.o
    ./src/Main.o: In function `main':
    /home/workspace/TESTCPP/Debug/../src/Main.cpp:17: undefined reference to `Voiture::test()'
    ./src/Voiture.o: (.rodata._ZTV7Voiture[vtable for Voiture]+0x10): undefined reference to `Voiture::addPassenger()'
    collect2: ld a retourné 1 code d'état d'exécution
    make: *** [TESTCPP] Erreur 1
    J'avoue que je ne comprends pas cette erreur de linkage... Un petit coup de pouce et vos conseils sont les bienvenues.

    Merci d'avance

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    159
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 159
    Points : 224
    Points
    224
    Par défaut
    Hello,
    Je vois plusieurs problèmes :

    - Il n'y a pas de fonction virtuelle `test` dans ta classe mère Vehicule (elle n'y est d'ailleurs pas définie du tout). Or si une fonction n'a pas été définie virtuelle (éventuellement pure)... elle n'est pas virtuelle ! Tu ne pourras donc pas appeler son implémentation de la classe fille à partir d'un pointeur sur la classe mère.
    (ça, c'est le premier message d'erreur)

    - La fonction virtuelle addPassenger de ta classe Vehicule est bien redéfinie dans ta classe fille, mais aucune implémentation n'est proposée dans le fichier .cpp
    (ça c'est le deuxième message d'erreur)

    Ps: à quoi sert ta classe Main ?

  3. #3
    Membre actif

    Inscrit en
    Août 2005
    Messages
    401
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 401
    Points : 228
    Points
    228
    Par défaut
    Coucou merci de ta réponse rapide.

    Ma classe Main va servir à instancier toutes mes classes. Je viens du java et en Java c'est la manière de faire... Si tu as une méthode plus propre en C++ je suis preneur.

    Pour la méthode test je ne veux pas qu'elle soit virtuelle mais que ce soit une méthode de la classe Voiture.

    Pour la méthode addpassenger je veux que cela soit une méthode virtuelle propre ayant été définit obligatoire dans Vehicule.

    J'ai donc décommenté la méthode addPassenger() dans Voiture.cpp mais j'ai toujours la même erreur :

    Building target: TESTCPP
    Invoking: GCC C++ Linker
    g++ -o "TESTCPP" ./src/Main.o ./src/Voiture.o
    ./src/Main.o: In function `main':
    /home/workspace/TESTCPP/Debug/../src/Main.cpp:17: undefined reference to `Voiture::test()'
    ./src/Voiture.o: (.rodata._ZTV7Voiture[vtable for Voiture]+0x10): undefined reference to `Voiture::addPassenger()'
    collect2: ld a retourné 1 code d'état d'exécution
    make: *** [TESTCPP] Erreur 1
    J'ai juste décommenté la méthode et pour test je ne sais pas quoi faire...

  4. #4
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Points : 176
    Points
    176
    Par défaut
    Salut à toi
    je pense que je peux t'aider :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void test() {
    	cout << "TEST OK" << endl;
    }
    /*
    void addPassenger() {
    	cout << "Ajout de passagers" << endl;
    }
    */
    1-il manque le nom de la classe devant la methode test définie dans voiture.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Voiture::test() {
    	cout << "TEST OK" << endl;
    }
    Le compilateur ne sait donc pas que tu définis la méthode test de Voiture or comme tu l'utilises dans le main() elle n'est pas considérée comme définie dans la classe Voiture : si tu supprimes la ligne v->test() le message d'erreur n'apparaîtra plus mais il est préférable de définir correctement la fonction dans voiture.cpp

    2-tu définis addPassenger comme commentaire (et sans le voiture:: avant) mais il faut obligatoirement la définir puisque tu l'as déclarée virtuelle dans véhicule (et la declarer dans voiture.hpp) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /*
    void voiture::addPassenger() {
    	cout << "Ajout de passagers" << endl;
    }
    */
    Voila, j'espère que ça marchera ^^

    Edit : c'est ce que disait valAa sur son deuxième point, mais je ne suis pas d'accord avec lui sur le premier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    - Il n'y a pas de fonction virtuelle `test` dans ta classe mère Vehicule (elle n'y est d'ailleurs pas définie du tout). Or si une fonction n'a pas été définie virtuelle (éventuellement pure)... elle n'est pas virtuelle ! Tu ne pourras donc pas appeler son implémentation de la classe fille à partir d'un pointeur sur la classe mère.
    (ça, c'est le premier message d'erreur)
    Ce serait le cas si akrogames écrivait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Vehicule *v = new Voiture(...);
    Or ici il écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Voiture *v = new Voiture(...);
    La méthode test n'a donc pas besoin d'être virtuelle et présente dans la classe Vehicule puisque c'est directement un objet voiture qui est instancié (à noter ici que pour le coup le pointeur n'a que peu d'intérêt puisque le polymorphisme est ici inutile)

    Sinon c'est vrai que ta classe Main semble étrange (pour ne pas dire totalement inutile ^^)

  5. #5
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 963
    Points
    32 963
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par valAa Voir le message
    - Il n'y a pas de fonction virtuelle `test` dans ta classe mère Vehicule (elle n'y est d'ailleurs pas définie du tout). Or si une fonction n'a pas été définie virtuelle (éventuellement pure)... elle n'est pas virtuelle ! Tu ne pourras donc pas appeler son implémentation de la classe fille à partir d'un pointeur sur la classe mère.
    (ça, c'est le premier message d'erreur)
    Le premier message n'est pas du tout cela.
    Il indique que Voiture::test n'est pas implémenté.
    Il est tout à fait autorisé de créer des méthodes non virtual dans une hiérarchie de classes.
    Dans le main il crée un pointeur Voiture et non véhicule, donc l'appel à voiture::test sera autorisé.

    Par contre test est implémenté comme méthode non liée à une classe... tu as une autre méthode test externe à toute classe ou tu as oublié Voiture:: pour indiquer qu'il s'agissait de la méthode test de Voiture ?

    undefined reference to `Voiture::addPassenger()'
    L'erreur parle d'elle-même : undefined reference.
    Tu n'as pas implémenté Voiture::addPassenger, tu n'as donc pas le droit d'instancier une Voiture.

    La classe Main ne sert à rien, tu as déjà une fonction main qui sert de point d'entrée à ton programme. (C'est la philosophie JAVA - tout objet -, que je n'aime pas du tout, débarasse-t'en ASAP ! Le C++ est multiparadigme ).
    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 actif
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    159
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 159
    Points : 224
    Points
    224
    Par défaut
    Citation Envoyé par Bousk
    Dans le main il crée un pointeur Voiture et non véhicule, donc l'appel à voiture::test sera autorisé.
    @ Lintel-oo et Bousk : en effet aux temps pour moi. Lu trop vite...

  7. #7
    Membre actif

    Inscrit en
    Août 2005
    Messages
    401
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 401
    Points : 228
    Points
    228
    Par défaut
    Super ! Cela fonctionne désormais. J'ai viré la classe Main comme susmentionné. Elle foutait le bordel et il avait des erreurs. Maintenant tout est fonctionnel.

    Je vais continuer mes tests d'héritage et essayer d'implanté des designs pattern. C'est les mêmes qu'en JAVA ? Oui c'est de l'objet c'est pareil.

    Merci de votre aide.

  8. #8
    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 518
    Points
    41 518
    Par défaut
    Il y a beaucoup de patterns qu'on peut faire en C++ et pas en Java, du fait des templates notamment.
    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.

  9. #9
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 963
    Points
    32 963
    Billets dans le blog
    4
    Par défaut
    Pourtant JAVA a un système de template non ?
    En cours nous utilisions des ArrayList<String>
    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.

  10. #10
    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 518
    Points
    41 518
    Par défaut
    Les "types génériques" ne sont pas aussi élaborés que les templates. Par exemple, tu ne peux pas utiliser la surcharge de fonction derrière, comme le C++ le permet.

    Code C++ : 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
    void FonctionSurchargee(int a) { /*...*/}
    void FonctionSurchargee(char const* a) { /*...*/}
     
    template<class T>
    void FonctionTemplate(T arg) { /*...*/ FonctionSurchargee(arg); /*...*/ }
     
    int main(void)
    {
    	int toto;
    	int* tata=NULL;
    	char const *titi="titi";
     
    	FonctionTemplate(toto); //OK
    	FonctionTemplate(tata); //Erreur, FonctionSurchargee() non définie pour int*
    	FonctionTemplate(titi); //OK
    }
    Il y a des patterns en C++ qui exploitent ça.

    PS: En fait, en Java ça passera peut-être la compilation (je ne sais pas, je connais surtout les types génériques de C#) mais on aura au mieux une ClassCastException à l'éxécution.
    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. méthode virtuelle pure et héritage
    Par Invité dans le forum Langage
    Réponses: 3
    Dernier message: 20/07/2009, 22h12
  2. Réponses: 3
    Dernier message: 17/09/2008, 13h52
  3. Réponses: 15
    Dernier message: 05/07/2007, 01h29
  4. Réponses: 23
    Dernier message: 16/03/2007, 20h21
  5. Problème avec une méthode virtuelle pure
    Par Burckel dans le forum C++
    Réponses: 4
    Dernier message: 05/12/2006, 13h00

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