PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > fr.comp.lang.c++ > Héritage et opérateur d'affectation
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Héritage et opérateur d'affectation

Réponse
 
LinkBack Outils de la discussion
Vieux 22/04/2008, 09h57   #1
Alexis Guillaume
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Héritage et opérateur d'affectation

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 !




  Réponse avec citation
Vieux 22/04/2008, 10h16   #2
David Côme
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Héritage et opérateur d'affectation

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.
  Réponse avec citation
Vieux 22/04/2008, 10h26   #3
Falk Tannhäuser
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Héritage et opérateur d'affectation

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
  Réponse avec citation
Vieux 23/04/2008, 08h07   #4
Alexis Guillaume
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Héritage et opérateur d'affectation

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.





  Réponse avec citation
Vieux 23/04/2008, 08h21   #5
Fabien LE LEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Héritage et opérateur d'affectation

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 pas
la 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&".)

  Réponse avec citation
Vieux 23/04/2008, 09h23   #6
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Héritage et opérateur d'affectation

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
  Réponse avec citation
Vieux 23/04/2008, 09h52   #7
Jean-Marc Bourguet
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Héritage et opérateur d'affectation

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
  Réponse avec citation
Vieux 23/04/2008, 10h12   #8
Alexis Guillaume
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Héritage et opérateur d'affectation

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
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 02h06.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,20301 seconds with 16 queries