Heritage et surdéfinition...

Heritage et surdéfinition... - C++ - Programmation

Marsh Posté le 14-09-2007 à 08:30:15    

Bonjour.
 
J'ai constaté un comportement du compilateur que je ne comprends pas trop.
 
Voici un résumé :
 
- j'ai une classe D (données) dont l'unique constructeur public a besoin d'une string
- j'ai une classe de base A qui implémente plusieurs versions d'une fonction f()
- j'ai une classe B qui dérive de A et qui implemente une version de f() prenant en argument une référence de classe D
 
Ca donne ça :

Code :
  1. /* La classe stockant des données */
  2. class D
  3. {
  4. public:            D(const ::std::string& );
  5.           virtual ~D();
  6. private:
  7.                     D();
  8.                     D(const D& );
  9. };
  10. /* Classe de base */
  11. class A
  12. {
  13. public:            A();
  14.           virtual ~A();
  15. protectedvoid f(int);
  16.             void f(char);
  17.             void f(const ::std::string& );
  18. };
  19. /* Classe specialisee */
  20. class B : public A
  21. {
  22. public:            B();
  23.           virtual ~B();
  24.               void toto();
  25. protected:    void f(const D& );
  26. };


 
Ce que je ne comprends pas, c'est ce que fait le compilateur lorsque depuis l'une des méthodes de la classe spécialisée B, j'appelle f() avec une string en argument :
 

Code :
  1. void B::toto()
  2. {
  3.    ::std::string s("bonjour" );
  4.    f(s);
  5. }


 
Là le compilateur construit un objet intermédiaire D et appelle B::f(const D& ).
Pourquoi ne va-t-il pas chercher directement la méthode A::f(const ::std::string& ) ????
 
Si je déclare le constructeur D :: D(const ::std::string& ) explicit, ça ne compile plus, car il ne trouve aucun constructeur adapté pour son objet intermédiaire (normal). Au moins ça me permet de déctecter mon problème.
 
Testé avec gcc et vc++.
 
Merci de vos lumières et désolé d'exposer ici mes lacunes en c++ !
 
[EDIT : oubli de faire dériver B de A]


Message édité par f4brice le 14-09-2007 à 09:48:27
Reply

Marsh Posté le 14-09-2007 à 08:30:15   

Reply

Marsh Posté le 14-09-2007 à 08:36:46    

On voit pas que B hérite de A :o

Reply

Marsh Posté le 14-09-2007 à 09:47:46    

Oups, c'est une erreur quand j'ai écrit le message. Je l'édite...

Reply

Marsh Posté le 14-09-2007 à 11:22:53    

Salut,

 

Il faut utiliser un using pour importer les méthodes de la classe de base pour lesquelles tu fais une surcharge. J'essaie de retrouver un lien expliquant ça, et j'édite mon post.

 

Edit: voilà: http://www.parashift.com/c++-faq-l [...] l#faq-23.9


Message édité par IrmatDen le 14-09-2007 à 11:24:33
Reply

Marsh Posté le 14-09-2007 à 12:17:24    

La FAQ te dit comment t'en sortir et suggères surtout d'éviter les mélanges.
 
 
Sinon c'est bien beau de cacher son constructeur de copie, seulement, faudrait aussi cacher operator=

Reply

Marsh Posté le 14-09-2007 à 18:09:05    

IrmatDen : merci pour ton lien. J'en sais un peu plus maintenant et l'astuce du "using" permet d'adresser mon problème.
Taz : tu as raison ; je pense rarement à le faire.
 

Reply

Marsh Posté le 14-09-2007 à 19:09:44    

Taz a écrit :

La FAQ te dit comment t'en sortir et suggères surtout d'éviter les mélanges.
 
 
Sinon c'est bien beau de cacher son constructeur de copie, seulement, faudrait aussi cacher operator=


ou mieux, dériver de boost::non_copyable

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed