Argh! Problème de constructeur de recopie et de surdéfinition de = [Résolu]

Signaler
Messages postés
159
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
26 février 2009
-
Messages postés
159
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
26 février 2009
-
Ca fait une semaine que j'eesaye de comprendre ce bug, mais rien n'y fait

(et je me sent tout frustré du coup , je dors plus, je mange plus, je bois plus ('fin non quand même pas...))



A la base, je fais une classe sur les matrices, mais je ne vais pas vous fournir celle-là car ce serait bien long...

Mais j'ai fait (spécialement pour vous ) une autre classe, qui fonctionne sur le même principe et qui a le meme problème de compilation...



Voici la classe buguée:





class A

{

int a;

public:

A()

{

a= 0;

}

int get_value()

{

return a;

}

void set_value(int new_a)

{

a =new_a;

}

A operator+(A& other)

{

A sum;

sum.set_value(this->get_value() + other.get_value());

return sum;

}

A& operator= (A& other)

{

this ->set_value(other.get_value());

return *this;

}

};





Immaginons que mon main() soit



int main()

{

A a,b,c;

a.set_value(1);

b.set_value(36);

c.set_value(42);

a = b+c;

return 0;

}



Alors il ne compile pas la ligne en rouge, et me dit:

Error: no match for 'operator' in 'a A::operator+(A&)((&c))

Error: Candidates are: A& A::operator=(A&)



Je comprend pas trop ce qu'il me veut , mais il est pas content le compilo !





Alors j'ai pensé faire ceci:



class A

{

int a;

bool tampon;

public:

A()

{

a =0;

tampon = false;

}

int get_value()

{

return a;

}

void set_value(int new_a)

{

a =new_a;

}

A& operator+(A& other)

{

A* sum = new A;

sum->tampon = true;

sum->set_value(this->get_value() + other.get_value());

return *sum;

}

A& operator= (A& other)

{

this ->set_value(other.get_value());

if(other.tampon)

delete &other;

return *this;

}

};





Mais malgré ma courte expérience en
programmation, ca me semble assez laid, on dirait du bricolage. Et en
plus si un gugus d'utilisateur (en l'occurence moi ) s'amuse à écrire:

A a,b;

a.set_value(1);

b.set_value(2);

while(1)

{

a+b;

}

La mémoire explose, car la matrice de résultat de a+b n'est pas détruite.





On m'a aussi proposé ceci, mais qui comporte le même problème de mémoire...



class TemporaryA;



class A

{

int a;

public:

A();

int get_value();

void set_value(int new_a);

TemporaryA& operator+(A& other);

A& operator =(A& other);

A& operator= (TemporaryA& other);

};



class TemporaryA : public A {};



A::A(){ a =0; }



int A::get_value(){ return a; }



void A::set_value(int new_a) { a= new_a; }



TemporaryA& A:: operator +(A& other) {

TemporaryA* sum = new TemporaryA;

sum->set_value(this->get_value() + other.get_value());

return *sum;

}



A& A::operator= (A& other) {

this ->set_value(other.get_value());

return *this;

}



A& A::operator =(TemporaryA& other) {

this->set_value(other.get_value());

delete &other;

return *this;

}



C'est un peu plus beau que ce que j'ai fait plus haut, mais c'est toujours aussi foireux pour la mémoire...



J'ai comme on dit "besoin d'un p'tit coup d'pouce"



ps:

Je suis obligé de surdéfinir les constructeurs car mon vrai projet est avec des matrices dynamiques...

Ne me dites pas de changer de language pour faire ca, je sais bien que
le c++ n'est pas top pour les math, mais c'est pour un projet officiel
en c++, donc je n'ai pas ce choix...

C'est pas méga urgent mais je dois quand même le rendre en janvier, et j'ai pas mal de boulot à côté...





MERCI BEAUCOUP !!!




Duchon.

13 réponses

Messages postés
15021
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
19 avril 2021
94
Hello,
l'opérateur "+" se surcharge comme suit:


A operator+(A& other1, A& other2);

Ce que tu as fait est pour l'opérateur "+="...

Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Messages postés
159
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
26 février 2009

Dans le cas de mes matrices, en friend alors ?

J'essayerai ce soir...

merci !




Duchon.
Messages postés
15021
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
19 avril 2021
94
Effectivement, j'ai oublié de préciser "friend" mais tu as corrigé tout seul...

Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Messages postés
9
Date d'inscription
lundi 10 mai 2004
Statut
Membre
Dernière intervention
20 avril 2006

Salut,

On peut régler le problème différemment, il suffit juste de rajouter les "const" qui manquent dans ton code sinon l'entête pour l'opérateur + peut bien être écrit comme tu l'as fait. Il compile chez moi avec les const rajoutés :

class A
{
int a;
public:
A() {
a=0;
}

int get_value() const {
return a;
}

void set_value(int new_a) {
a=new_a;
}


A operator+(const A& other) const{
A sum;
sum.set_value(this->get_value() + other.get_value());
return sum;
}


A& operator=(const A& other)
{
this->set_value(other.get_value());
return *this;
}
};

De cette façon on évite les opérateur friend :)

A bientôt

_________
Aquarian
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Non, normalement l'opérateur + ca doit etre un friend, et pas une fonction membre.
Messages postés
9
Date d'inscription
lundi 10 mai 2004
Statut
Membre
Dernière intervention
20 avril 2006

Ca ne doit pas être obligatoirement un friend...
Les deux s'utilisent, je ne pense pas qu'une méthode soit meilleure par rapport à l'autre mais peut-être qu'il y a une raison telle qu'utiliser un friend dans ce cas serait préférable.

_________
Aquarian
Messages postés
159
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
26 février 2009

Vous battez pas !

Je vais reagarder ca tranquillement ce soir (pas le net chez moi...) et je vous dirai demain si je m'en suis sorti



Merci beaucoup en tous cas !

Duchon.
Messages postés
9
Date d'inscription
lundi 10 mai 2004
Statut
Membre
Dernière intervention
20 avril 2006

Mais non, ma réponse est peut-être un peu sèche mais ce n'était pas voulu :(
En fait j'aimerai savoir comment l'un des deux choix peut-être justifié suivant les cas.
_________
Aquarian
Messages postés
15021
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
19 avril 2021
94
sans friend --> surcharge d'opérateurs internes à la classe (+=,-=,...)
avec friend --> surcharge d'opérateurs externes (+, -, ...)

A priori, la déclaration des opérateurs avec friend permettrait à ces derniers de manipuler les données membres de leurs opérandes...

Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Messages postés
159
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
26 février 2009

et je peux laisser le += -= *= ... dans la classe et mettre les opérateur binaire en friend ?
Duchon.
Messages postés
15021
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
19 avril 2021
94
C'est ce que je fais, étant donné qu'avec les opérateurs internes, tu agis directement sur l'objet courant

Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Messages postés
9
Date d'inscription
lundi 10 mai 2004
Statut
Membre
Dernière intervention
20 avril 2006

Merci pour vos réponses

A bientôt.
_________
Aquarian
Messages postés
159
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
26 février 2009

Merci tout le monde !
Duchon.