Polymorphisme pour les surchage d'opérateur !

Problème de conception

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour.

Je suis actuellement un cours à l'université dans lequel je dois élaborer un programme orienté objet cependant je me heurte à un problème de conception à plusieurs endroit de mon programme. J'ai des données dans mon programme pour lesquelles je veux surcharger les operateur + - * / de manière différente selon les types d'objets. J'ai des données de la forme.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class class_mere
{
    public:
        virtual class_mere& operator+(class_mere&) = 0;
        // On veut que cet operateur soit défini pour toutes les classes filles
}
class classe_fille_1
{
}
class classe_fille_2
{
}

Et je veux qu'on puisse utiliser operator+ sur des pointeur de class_mere tels que suivant si ils pointent sur des objets classe_fille_1 ou classe_fille_2 ils renvoient ceci :

objet classe_fille_1 + objet classe_fille_2 donne objet classe_fille_1

objet classe_fille_1 + objet classe_fille_1 donne objet classe_fille_1

objet classe_fille_2 + objet classe_fille_1 donne objet classe_fille_1

objet classe_fille_2 + objet classe_fille_2 donne objet classe_fille_2.

Cependant faire :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class class_mere
{
    public:
        virtual class_mere& operator+(class_mere&) = 0;
        // On veut que cet operateur soit défini pour toutes les classes filles
}
class classe_fille_1
{
    public:
        classe_mere& operator+(class_mere&);
}
class classe_fille_2
{
    public:
        classe_fille_2& operator+(classe_fille_2&);
        classe_fille_1& operator+(classe_fille_1&);
}

Ne marche pas car classe_fille_2 est alors considérée comme virtuelle !

Comment résoudre ce problème de conception qui me bloque vraiment ?

Merci beaucoup :)

Édité par plougue

+0 -0

Salut,

Ce serait plus facile de s'y repérer en sortant les opérateurs des classes, tu aurais par exemple :

1
MaClasseMere operator+(const MaClasseFille1& lhs, const MaClasseFille2& rhs);

Il ne faut pas retourner une référence mais un objet !

Après, je ne suis pas sûr que l'on puisse reproduire ce que tu veux faire.

Édité par victorlevasseur

+0 -0

Surcharge d'opérateurs et héritage public ne font pas bon ménage. En effet, tu essaies de fusionner deux concepts antithétiques : sémantique de valeur et sémantique d'entité. Je te laisse chercher si tu ne connais pas. ;)

Et une classe virtuelle, ça ne veut rien dire. :)

Plus on apprend, et, euh… Plus on apprend. | Coliru, parfait pour tester ses codes sources !

+1 -0
Auteur du sujet

@mehdidou99 Pardon je voulais dire classe abstraite et pas classe virtuelle évidemment ;) ! Je vais me renseigner sur ces deux concepts !

@Victorlevasseur je veux jamais renvoyer d'objet de type classmere, je mettais justement une réference pour pouvoir mettre un objet classe_fille dans une réference de classe_mere !

EDIT : Après m'être renseigné il s'avère que je veux effectivement faire une classe avec une sémantique de valeur qui a une fonction virtuelle pure ! Ce qu'une source considère illogique.

Cependant l'idée est de pouvoir programmer un nombre soit en temps qu'objet fraction (deux integer) soit en temps que flottant (un float), les deux pouvant être égaux mais devant appartenir à deux classes différentes et pouvant être codé en tant réference d'une autre classe nommé "nombre" ! Et l'idée serait de pouvoir additionner deux nombre ainsi sans savoir de quel classe fille ils proviennent.

Est-ce que c'est impossible à faire en C++ ? Est-ce une limite du langage ou c'est juste moi qui me gourre quelque part ?

Merci pour vos réponses !

Édité par plougue

+0 -0

Oui, mais l'opérateur + doit renvoyer un objet et non une référence : sinon, l'objet construit dans le corps de l'opérateur est perdu et la référence devient invalide.

Je pense que tu as un problème sémantique dans tes classes.

+0 -0

Pour ce genre de choses, l'objet n'est pas adapté.

Il y a des bidouilles (idiome enveloppe-lettre, framework d'objets réguliers par S.Parent et A.Stepanov, IIRC), mais rien de propre.

En C++, tu vas te prendre deux murs:

  • le premier est le mur du slicing : quel est le type du retour ? (qui doit impérativement être copié -> impossible de retourner une référence/pointeur)
  • le second est le mur du double dispatch: le polymorphisme ne doit pas s'appliquer sur un, mais sur deux arguments. Fraction + double, et Fraction + Fraction, complexe + fraction… devraient renvoyer des choses différentes. (Même pb dans les autres langages sans double dispatch comme Java et plein, plein d'autres)

Et en plus, tu as le mur du pas compatible avec l'OO. P.ex., il est impossible d'écrire une opération de test d'égalité entre objets de types différents d'une même hiérarchie qui respecte les 3 propriétés mathématiques de l'égalité : symétrique, réflexif, transitif. Soit tu sacrifies une des 3 propriétés, soit tu sacrifies le LSP. (cf Effective Java 2nde édition de Bloch)

Édité par lmghs

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte