|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Bonjour à tous !
Le code suivant ne compile pas : ----- #include <string> class A { public: A const & operator = (std::string const &str) {} A const & operator += ( std::string const &str ) {} }; class B : public A { }; int main() { B b; b += "titi"; // Ok b = "titi"; // Erreur } ----- heritage.cc: In function ‘int main()’: heritage.cc:14: error: no match for ‘operator=’ in ‘b = "titi"’ heritage.cc:8: note: candidates are: B& B: perator=(const B&)----- Ce que je ne comprends pas c'est que l'opérateur += (utilisé ici pour l'exemple) fonctionne bien, mais pas l'affectation. Cela signifie donc que l'opérateur = est traité différement des autres ? Bon, en supposant qu'il ne soit vraiment pas possible d'avoir un opérateur = dans une classe de base et de s'en servir dans les classes dérivées, que puis-je utiliser d'autre ? Mes classes dérivées ne contiendront jamais aucune variable membre supplémentaire, mais juste des fonctions membres pour accéder différemment aux données. C'est pourquoi j'aimerais bien pouvoir utiliser l'affectation, sans redéfinir l'opérateur à chaque fois... Alexis Guillaume PS : ceci étant mon premier post par l'intermédiaire de google groups, je croise les doigts pour tout fonctionne correctement (accents, lignes coupées, etc) ; si ce n'est pas le cas merci de me le signaler ! |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Tue, 22 Apr 2008 10:57:59 +0200, Alexis Guillaume
<alexis.c.guillaume@gmail.com> wrote: > Bonjour à tous ! > Le code suivant ne compile pas : > ----- > #include <string> > > class A { > public: > A const & operator = (std::string const &str) {} > A const & operator += ( std::string const &str ) {} > }; > class B : public A { > }; > int main() { > B b; > b += "titi"; // Ok > b = "titi"; // Erreur > } > ----- > heritage.cc: In function ‘int main()’: > heritage.cc:14: error: no match for ‘operator=’ in ‘b = "titi"’ > heritage.cc:8: note: candidates are: B& B: perator=(const B&)> ----- > Ce que je ne comprends pas c'est que l'opérateur += (utilisé ici pour > l'exemple) fonctionne bien, mais pas l'affectation. Cela signifie donc > que l'opérateur = est traité différement des autres ? > > Bon, en supposant qu'il ne soit vraiment pas possible d'avoir un > opérateur = dans une classe de base et de s'en servir dans les classes > dérivées, que puis-je utiliser d'autre ? Mes classes dérivées ne > contiendront jamais aucune variable membre supplémentaire, mais juste > des fonctions membres pour accéder différemment aux données. C'est > pourquoi j'aimerais bien pouvoir utiliser l'affectation, sans > redéfinir l'opérateur à chaque fois... > > Si je ne me trompe pas, l'opérateur = n'est pas hérité de la classe mère. > Alexis Guillaume > PS : ceci étant mon premier post par l'intermédiaire de google groups, > je croise les doigts pour tout fonctionne correctement (accents, > lignes coupées, etc) ; si ce n'est pas le cas merci de me le > signaler ! > Tout marche très bien. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Alexis Guillaume wrote:
> Bonjour à tous ! > Le code suivant ne compile pas : > ----- > #include <string> > > class A { > public: > A const & operator = (std::string const &str) {} > A const & operator += ( std::string const &str ) {} > }; > class B : public A { > }; > int main() { > B b; > b += "titi"; // Ok > b = "titi"; // Erreur > } > ----- > heritage.cc: In function ‘int main()’: > heritage.cc:14: error: no match for ‘operator=’ in ‘b = "titi"’ > heritage.cc:8: note: candidates are: B& B: perator=(const B&)C'est normal - l'opérateur = n'est pas hérité. > Bon, en supposant qu'il ne soit vraiment pas possible d'avoir un > opérateur = dans une classe de base et de s'en servir dans les classes > dérivées, que puis-je utiliser d'autre ? Mes classes dérivées ne > contiendront jamais aucune variable membre supplémentaire, mais juste > des fonctions membres pour accéder différemment aux données. C'est > pourquoi j'aimerais bien pouvoir utiliser l'affectation, sans > redéfinir l'opérateur à chaque fois... Il n'y a pas le choix, il faut redéfinir l'affectation dans la classe dérivée, mais heureusement on peut faire appel à l'affectation de la classe de base pour cela. S'il existe plusieurs opérateurs d'affectation pour des types différents, un template fait l'affaire : class B : public A { public: template<typename T> B& operator=(T const& t) { A: perator=(t);return *this; } }; Falk |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Apr 22, 11:26am, Falk Tannhäuser <falk.tannhau...@crf.canon.fr>
wrote: > Il n'y a pas le choix, il faut redéfinir l'affectation dans la classe > dérivée, mais heureusement on peut faire appel à l'affectation de la > classe de base pour cela. S'il existe plusieurs opérateurs d'affectation > pour des types différents, un template fait l'affaire : > > class B : public A > { > public: > template<typename T> B& operator=(T const& t) > { > A: perator=(t);> return *this; > } > > }; Cette solution me semble acceptable ; certes il va falloir réécrire ce code dans chaque classe fille, mais au moins le compilateur protestera de manière claire si on l'oublie... Je préfère cela à l'utilisation d'un opérateur différent (obfuscation !) et c'est quand même plus beau qu'un appel de fonction. Problème résolu donc... Par contre pour la théorie je ne comprends pas trop le pourquoi du comment... Je vois bien pourquoi on n'hérite pas de l'opérateur d'affectation quand celui ci est de la forme : B const & operator = (B const &); J'imagine que cela résulterait dans beaucoup de cas en une affectation partielle (seule les données de la classe de base seront copiées). Même si je trouve cela inhabituel en C++ de voir une règle pour pour protéger le programmeur de ses propres bêtises ;-) Mais en ce qui me concerne, mon opérateur d'affectation prend une std::string, et il n'éxiste même pas de conversion implicite vers ma classe depuis une std::string, alors pourquoi ne pas en permettre l'héritage ? Alexis Guillaume. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Wed, 23 Apr 2008 00:07:55 -0700 (PDT), Alexis Guillaume
<alexis.c.guillaume@gmail.com>: >Par contre pour la théorie je ne comprends pas >trop le pourquoi du comment... Imagine le cas suivant : struct A { void f (std::string const&); }; struct B: A { void f (B const&); }; int main() { B b; b.f ("Hello"); // erreur ! } Étant donné qu'une fonction B::f() existe, la fonction A::f() n'est pas héritée par B, même si les arguments ne coïncident pas. Remplace f par operator= et tu retombes sur le cas qui t'occupe. En effet, B a forcément un "operator=(B const&)", éventuellement implicite. Par ailleurs, note que A: perator= et B: perator= ne renvoient pasla même chose : un A& et un B&, respectivement. (Note aussi qu'il y a une erreur dans ton code d'origine : A: perator= renvoie un A&, pas un "A const&".) |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Apr 22, 10:57 am, Alexis Guillaume <alexis.c.guilla...@gmail.com>
wrote: > Le code suivant ne compile pas : > ----- > #include <string> > class A { > public: > A const & operator = (std::string const &str) {} > A const & operator += ( std::string const &str ) {}}; > class B : public A {}; > int main() { > B b; > b += "titi"; // Ok > b = "titi"; // Erreur > } > ----- > heritage.cc: In function ?int main()?: > heritage.cc:14: error: no match for ?operator=? in ?b = "titi"? > heritage.cc:8: note: candidates are: B& B: perator=(const B&)> ----- > Ce que je ne comprends pas c'est que l'opérateur += (utilisé > ici pour l'exemple) fonctionne bien, mais pas l'affectation. > Cela signifie donc que l'opérateur = est traité différement > des autres ? Un peu. En fait, à cet égard, il se comporte exactement comme n'importe quelle autre fonction. Seulement, si toi, tu ne déclare pas de operator= de copie dans une classe, le compilateur en déclare un pour toi. Un qui cache la déclaration dans la classe de base. C'est exactement comme si la fonction s'appeler « f », et que tu avais déclaré un « f( B const& ) » dans ta classe B. La solution en est la même aussi: ajouter un « using A: perator= ; » dans la class B.> Alexis Guillaume > PS : ceci étant mon premier post par l'intermédiaire de google > groups, je croise les doigts pour tout fonctionne correctement > (accents, lignes coupées, etc) ; si ce n'est pas le cas merci > de me le signaler ! Pas de problème, mais si tu utilise Firefox comme butineur, je te suggère l'add-on « it's all text », pour pouvoir éditer les messages avec ton éditeur préféré. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
James Kanze <james.kanze@gmail.com> writes:
> Pas de problème, mais si tu utilise Firefox comme butineur, je > te suggère l'add-on « it's all text », pour pouvoir éditer les > messages avec ton éditeur préféré. Genial. Merci. A+ -- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/...ite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On Apr 23, 10:23am, James Kanze <james.ka...@gmail.com> wrote:
> Un peu. En fait, à cet égard, il se comporte exactement comme > n'importe quelle autre fonction. Seulement, si toi, tu ne > déclare pas de operator= de copie dans une classe, le > compilateur en déclare un pour toi. Un qui cache la déclaration > dans la classe de base. C'est exactement comme si la fonction > s'appeler « f », et que tu avais déclaré un > « f( B const& ) » dans ta classe B. > > La solution en est la même aussi: ajouter un > « using A: perator= ; » dans la class B.Merci à tous pour l'explication et la solution. Je constate que l'on peut toujours autant compter sur les habitués de ce forum en cas de souci ! > > Alexis Guillaume > > PS : ceci étant mon premier post par l'intermédiaire de google > > groups, je croise les doigts pour tout fonctionne correctement > > (accents, lignes coupées, etc) ; si ce n'est pas le cas merci > > de me le signaler ! > > Pas de problème, mais si tu utilise Firefox comme butineur, je > te suggère l'add-on « it's all text », pour pouvoir éditer les > messages avec ton éditeur préféré. Merci beaucoup. Je suis en effet bien plus heureux en utilisant [Nom de l'éditeur censuré pour ne pas lancer une flame-war !]. :-) -- Alexis Guillaume |
|
![]() |
| Outils de la discussion | |
|
|