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

MFC Discussion :

surcharge de fonction virtuelle et VC++6


Sujet :

MFC

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 46
    Par défaut surcharge de fonction virtuelle et VC++6
    Bonjour,

    j'ai un code source développé sous linux, qui compile donc avec gcc (et VS express 2005 accesoirement) mais pas avec visual studio 6 (que je dois pourtant utiliser pour fusionner avec un autre code). Le problème étant:

    c:\savsimth\smaexpr.h(56) : error C2555: 'ValExpr<T>::optim' : overriding virtual function differs from 'SMAExpr::optim' only by return type or calling convention
    c:\savsimth\smaexpr.h(28) : see declaration of 'SMAExpr'
    c:\savsimth\smaexpr.h(58) : see reference to class template instantiation 'ValExpr<T>' being compiled
    c:\savsimth\smaexpr.h(56) : error C2555: 'ValExpr<bool>::optim' : overriding virtual function differs from 'SMAExpr::optim' only by return type or calling convention
    c:\savsimth\smaexpr.h(28) : see declaration of 'SMAExpr'
    c:\savsimth\smaexpr.h(89) : see reference to class template instantiation 'ValExpr<bool>' being compiled
    c:\savsimth\smaexpr.h(100) : error C2555: 'CompExpr::optim' : overriding virtual function differs from 'SMAExpr::optim' only by return type or calling convention
    c:\savsimth\smaexpr.h(28) : see declaration of 'SMAExpr'
    c:\savsimth\smaexpr.h(56) : error C2555: 'ValExpr<float>::optim' : overriding virtual function differs from 'SMAExpr::optim' only by return type or calling convention
    c:\savsimth\smaexpr.h(28) : see declaration of 'SMAExpr'
    c:\savsimth\smaexpr.h(112) : see reference to class template instantiation 'ValExpr<float>' being compiled
    c:\savsimth\agent.cpp(117) : error C2371: 'si' : redefinition; different basic types
    c:\savsimth\agent.cpp(113) : see declaration of 'si'
    les codes étant :
    virtual SMAExpr* optim() {return this;}

    virtual ValExpr<T>* optim() {return this;}
    et des scpécialisations dans les sous classes ensuite

    Que faire?

  2. #2
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    VC6 est connu pour ne pas respecter le standard, donc bon
    Maintenant, tu peux donner le prototype des 2 fonctions, l'original et celle dans la dérivée ?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 46
    Par défaut
    virtual SMAExpr * optim ()
    ValExpr< T > * optim ()
    virtual ValExpr< T > * optim ()
    ValExpr< bool > * optim ()

    En fait ce qui ne lui plait peut être pas c'est d'avoir le même prototype de fonction dans 2 sous classes différentes? Ou juste que celle qui retourne un SMAExpr* ai le même code que celle qui retourne un ValExpr* ?

  4. #4
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Attends, je t'ai demandé 2 prototypes, tu m'en donnes 4, qui va où ?

  5. #5
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Petite note de nomenclature:
    - surcharger (anglais overload), c'est avoir plusieurs fonctions avec des signatures differentes mais le meme nom;
    - remplacer une fonction virtuelle dans une classe derivee (anglais override), ce dit redefinir ou supplanter.

    Citation Envoyé par grodwar
    c:\savsimth\smaexpr.h(56) : error C2555: 'ValExpr<T>::optim' : overriding virtual function differs from 'SMAExpr::optim' only by return type or calling convention

    les codes étant :
    virtual SMAExpr* optim() {return this;}

    virtual ValExpr<T>* optim() {return this;}
    et des scpécialisations dans les sous classes ensuite
    Tu utilises des retours covariants, la possibilite de supplanter une fonction membre retournant un pointeur ou une reference vers sa classe par une autre retournant un pointeur ou une reference vers la classe derivee. Ca ne m'etonnerait pas du tout que VC6 n'implemente pas cela. La technique habituelle est d'eviter de faire un retour covariant et d'utiliser la possibilite de remplacer des fonctions membres non virtuelles (c'est un des rares cas legitimes pour le faire).

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Base {
    public:
       Base* f() { return do_f(); }
    private:
       virtual Base* do_f() { return this; }
    };
     
    class Derivee: public Base {
    public:
       Derivee* f() { return static_cast<Derivee*>(do_f()); }
    private:
       /* virtual */ Base* do_f() { return this; }
    };
    les points importants etant:
    - f() n'est pas virtuelle mais on change son type de retour;
    - do_f() est virtuelle et on ne change pas son type de retour.

    Edit: Correction du code, il faut toujours tester avec de poster

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 46
    Par défaut
    Citation Envoyé par Miles
    Attends, je t'ai demandé 2 prototypes, tu m'en donnes 4, qui va où ?
    Classe mère: SMAExpr avec SMAExpr * optim ()
    ValExpr(héritant de SMAExpr) avec virtual ValExpr< T > * optim ()
    Opexpr (héritant de ValExpr<T>) virtual ValExpr<T>* optim();
    CompExpr (héritant de ValExpr<bool>) ValExpr<bool>* optim();

    @JeanMarc: il suffirait "juste" d'enlever le virtual partout donc?

  7. #7
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Si tu enlèves le virtual, tu n'as plus la possibilité d'appeler la fonction de la classe dérivée à la place de celle de la classe mère, c'est embêtant !

  8. #8
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par grodwar
    @JeanMarc: il suffirait "juste" d'enlever le virtual partout donc?
    Est-ce que c'est ce que j'ai fait dans l'exemple que j'ai donne?

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 46
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Est-ce que c'est ce que j'ai fait dans l'exemple que j'ai donne?
    Effectivement non.

    En relisant ton code, il faut réimplémenter une sous méthode privée qui renvoie le bon type? Mais toi dans la dérivée tu renvoie une Base* quand même alors que je voudrais un dérivée* O.o


    Merci beaucoup pour ces éclaircissements

  10. #10
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par grodwar
    En relisant ton code, il faut réimplémenter une sous méthode privée qui renvoie le bon type? Mais toi dans la dérivée tu renvoie une Base* quand même alors que je voudrais un dérivée* O.o
    Il ne faut pas utiliser do_f() mais f() qui fait le cast. Le code que j'ai ecrit ne fait rien d'autre que ce que fait le compilateur quand il implemente les retours covariants.

    (Note: j'ai edite le code, j'avais oublie l'heritage et le cast qui est necessaire; le static_cast est sur tant que les classes derivees de Derivee ne font rien de stupide).

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 46
    Par défaut
    je reviens à la charge car je n'ai pas du tout comprendre, j'ai fait ça:

    dans SMAExpr:
    SMAExpr* optim() {return do_optim();}
    virtual SMAExpr* do_optim() {return this;}

    et dans ValExpr:
    ValExpr<T>* optim() {return static_cast<ValExpr*>(do_optim());}
    virtual SMAExpr<T>* do_optim() {return this;}

    et j'ai la compil suivante:
    SMAExpr.cpp
    c:\savsimth\smaexpr.h(63) : error C2059: syntax error : '<'
    c:\savsimth\smaexpr.h(64) : see reference to class template instantiation 'ValExpr<T>' being compiled
    c:\savsimth\smaexpr.h(63) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body
    c:\savsimth\smaexpr.h(64) : see reference to class template instantiation 'ValExpr<T>' being compiled
    c:\savsimth\smaexpr.h(63) : error C2059: syntax error : '<'
    c:\savsimth\smaexpr.h(95) : see reference to class template instantiation 'ValExpr<bool>' being compiled
    c:\savsimth\smaexpr.h(63) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body
    c:\savsimth\smaexpr.h(95) : see reference to class template instantiation 'ValExpr<bool>' being compiled
    c:\savsimth\smaexpr.h(63) : error C2059: syntax error : '<'
    c:\savsimth\smaexpr.h(119) : see reference to class template instantiation 'ValExpr<float>' being compiled
    c:\savsimth\smaexpr.h(63) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body
    c:\savsimth\smaexpr.h(119) : see reference to class template instantiation 'ValExpr<float>' being compiled
    c:\savsimth\smaexpr.h(63) : error C2059: syntax error : '<'
    c:\savsimth\smaexpr.h(148) : see reference to class template instantiation 'ValExpr<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >' being compiled
    C:\SavSimTh\SMAExpr.cpp(39) : see reference to class template instantiation 'OpExpr<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >' being compiled
    c:\savsimth\smaexpr.h(63) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body
    c:\savsimth\smaexpr.h(148) : see reference to class template instantiation 'ValExpr<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >' being compiled
    C:\SavSimTh\SMAExpr.cpp(39) : see reference to class template instantiation 'OpExpr<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >' being compiled
    Error executing cl.exe.


    et juste pour fun j'ai remplacer virtual SMAExpr<T>* do_optim() {return this;}
    par virtual void* do_optim() {return this;} et là il me refait des erreurs d'override ....

  12. #12
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    return static_cast<ValExpr<T>*>(do_optim())
    non ?
    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.

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 46
    Par défaut
    Effectivement ça me parait mieux médinox mais ca ne compile toujours.

    Je me demandais aussi pourquoi dans la classe dérivée, la méthode do_f() retourne un pointeur sur le type de base, car le "this" renvoie normalement un pointeur sur le type dérivé? C'est pour pouvoir avoir la méthode f() avec un code différent (et un retour différent évidemment)?


    (désolé pour les questions bêtes mais dur dur de mixer du code iso et VC++6 quand on est débutant )

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Comme VC++6 n'accepte pas les "retours covariants", ta fonction virtuelle do_f() doit avoir exactement le même type de retour que celle de la classe mère.

    Donc, do_f() retourne un pointeur sur le type de base.
    Donc, la fonction non-virtuelle f(), qui appelle do_f(), doit convertir le pointeur retourné en pointeur de son type.
    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.

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 46
    Par défaut
    Je comprends pas grand chose à ce vC++ 6 il y a un paquet de truc (surtout les template) avec lesquels il a du mal... c'est une vrai horreur d'importer du code dedans.


    En passant quelqu'un a une idée générale si l'importation d'un projet concu pour VC++6 en VC++ 2005 est long?

  16. #16
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    En passant quelqu'un a une idée générale si l'importation d'un projet concu pour VC++6 en VC++ 2005 est long?
    L'importation du projet seulement quelques secondes, mais la correction du code peut être très longue, surtout si tu utilisais beaucoup de choses non standard que VC6 autorisait.

    Sinon pour ce genre de question il faut aller sur le forum VC++, il y a plein d'infos à ce sujet ; il y a également un tutoriel de farscape sur la migration de projets VC6 -> VC2005.

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 46
    Par défaut
    j'ai toujours mes sympathiques: "error C2059: syntax error : '<'
    c:\savsimth\smaexpr.h(64) : see reference to class template instantiation 'ValExpr<T>' being compiled"

    avec la déclaration de la classe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <class T> class ValExpr : public SMAExpr
    {
    public:
    	virtual string type() {return typeid(T).name();}
    	virtual T val(Entity *a = NULL) = 0;
    			ValExpr<T>* optim() {return static_cast<ValExpr<T>*>(do_optim());}
    	virtual string asString() {return type();}
     
    private:
    	 virtual SMAExpr<T>* do_optim() {return(this);}
    };
    est-ce encore un bug de VC++6?
    Balises codes ajoutées, pensez-y la prochaine fois...

  18. #18
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Quelle ligne ??

  19. #19
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par grodwar
    j'ai toujours mes sympathiques: "error C2059: syntax error : '<'
    c:\savsimth\smaexpr.h(64) : see reference to class template instantiation
    est-ce encore un bug de VC++6?
    Non.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <class T> class ValExpr : public SMAExpr
    {
    public:
    	virtual string type() {return typeid(T).name();}
    	virtual T val(Entity *a = NULL) = 0;
    			ValExpr<T>* optim() {return static_cast<ValExpr<T>*>(do_optim());}
    	virtual string asString() {return type();}
     
    private:
    	 virtual SMAExpr* do_optim() {return(this);}
    };

  20. #20
    Membre averti
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 46
    Par défaut
    Merci, ça ne m'avait même pas effleurer l'esprit :/ (noob powah).

    Une autre question si vous êtes amateur:
    erreur de compil:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Failed to specialize function template 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall SMAParser::str(T)'
            With the following template arguments:
            'char'
    code de la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<typename T> string SMAParser::str(T val)
    {
    	ostringstream ss;
    	ss << val;
    	return ss.str();
    };
    Le problème ici est bien qu'il n'arrive pas instancier SMAParser::str pour les char? Alors que celle-ci n'utilise qu'une fonction censée marcher avec les char.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Surcharge de fonction virtuelle pure
    Par lg_53 dans le forum C++
    Réponses: 4
    Dernier message: 07/11/2014, 15h26
  2. Surcharger une fonction virtuelle
    Par pierreJTL dans le forum Débuter
    Réponses: 3
    Dernier message: 18/06/2012, 14h44
  3. Réponses: 16
    Dernier message: 21/05/2007, 01h04
  4. Réponses: 10
    Dernier message: 22/03/2006, 10h49
  5. Surcharge de fonction d'un edit dynamique
    Par Tartar Ukid dans le forum C++Builder
    Réponses: 4
    Dernier message: 13/10/2003, 11h56

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