problème operateur =

problème operateur = - C++ - Programmation

Marsh Posté le 02-02-2011 à 17:51:21    

Bonjours,
je m'arrache les cheveux depuis quelques jours sur une erreur de compilation,  
Je cherche a recréée la classe string. Lors de la compilation apparaît cette erreur "no match for 'operator='" lors de l'exécution de la ligne c=a+b où ces trois variable sont de type chaine (la classe que j'ai créé). Mais le problème c'est que une ligne telle que a+b ou c=a marche très bien.Pour précision je code avec code block 10.05.
 
Voici mon code
 
class chaine
{
    private :
    int n;
    char *p;
    public :
 
    //constructeur et destructeur
 
    chaine(char *T);//constructeur a partir d'une chaine
    ~chaine();//destructeur
    chaine(chaine &T);//constructeur de recopi
    chaine();//constructeur sans argument
 
    //fonction
    //int longueuer(chaine T);//renvoi la longueur de la chaine
    chaine & operator= (chaine &T);//permet l'égalisation entre deux chaine
    //char & operator[](int i);
    void affiche(void);
 
    //fonction amis
    friend chaine operator+(chaine a,chaine b);
    friend int operator==(chaine a,chaine b);
};
 
//constructeur et destructeur
chaine::chaine()
{
    n=0;
    p=NULL;
}
 
chaine::~chaine()
{
    delete p;
}
 
chaine::chaine(chaine &T)
{
    int i;
    n=T.n;
    p=new char[n];
    for(i=0;i<=n;i++)
    {
        *(p+i)=*(T.p+i);
    }
}
 
chaine::chaine(char *T)
{
    int lg=0,i=0;
    while(T[i]!='\0')//trouver la longeur de la chaine transmise;
    {
        lg++;
        i++;
        cout<<i<<endl;
    }
    n=lg+1;//pour'\0'
    p=new char [n];
    for(i=0;i<n;i++)//recopie de '\0'
    {
        *(p+i)=*(T+i);
    }
}
//fonction
void chaine::affiche(void)
{
    cout<<p<<endl;
}
 
chaine & chaine::operator =(chaine &T)
{
    int i;
    if(&T!=this)
    {
        delete p;
        n=T.n;
        p=new char[n];
        for(i=0;i<n;i++)
        {
            *(p+i)=*(T.p+i);
        }
    }
    return *this;
}
//fonction amis
int operator== (chaine a,chaine b)
{
    int egau=1,i;
    if(a.n==b.n)
    {
        for(i=0;i<a.n;i++)
        {
            if(*(a.p+i)!=*(b.p+i))
            {
                egau=0;
            }
        }
    }
    return egau;
}
 
chaine operator+(chaine a,chaine b)
{
    chaine somme;
    int i;
    somme.n=a.n+b.n+1;
    somme.p=new char[somme.n];
    for(i=0;i<a.n;i++)
    {
        *(somme.p+i)=*(a.p+i);
    }
    for(i=0;i<=b.n;i++)
    {
        *(somme.p+i+a.n)=*(b.p+i);
    }
    *(somme.p+somme.n)='\0';
    return somme;
}
 
en espérant que l'on pourra m'aider car je suis bientot chauve

Reply

Marsh Posté le 02-02-2011 à 17:51:21   

Reply

Marsh Posté le 02-02-2011 à 18:12:43    

chaine & operator= (chaine const&T);


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 02-02-2011 à 18:13:46    

Je n'ai regarder ton code en detail, mais d'apres ce que je vois cela devrait fonctionner.  
 
Pourrais tu poster le code qui pose probleme?

Reply

Marsh Posté le 02-02-2011 à 18:14:46    

Un Programmeur a écrit :

chaine & operator= (chaine const&T);


 
je suis d'accord sur l'utilisation de const, mais ca devrait marcher sans auss, non ?

Reply

Marsh Posté le 02-02-2011 à 18:16:10    

Tu ne peux pas passer un temporaire (ce que le resultat de a+b est) a une reference non const.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 02-02-2011 à 18:30:31    

ca depend ptet du compilateur (ce qui m'etonnerais), mais sur visual 2008:

Code :
  1. struct Nombre {
  2.     Nombre(int a = 0) : _a (a)    {}
  3.  
  4.     Nombre& operator=(Nombre& n) {
  5.         _a = n._a;
  6.         return *this;
  7.     }
  8.  
  9.     int _a;
  10. };
  11.  
  12. Nombre operator+ (const Nombre& n, const Nombre& m) {
  13.     return Nombre(n._a + m._a);
  14. }
  15.  
  16. void main() {
  17.     Nombre un(1), deux(2);
  18.     Nombre somme;
  19.        somme = un + deux;
  20.     std::cout << somme._a << std::endl;
  21. }

Reply

Marsh Posté le 02-02-2011 à 18:52:12    

J'ai essayer avec const et sa ne marche pas. voici mon main
int main()
{
    chaine a("salut" ),b(" l'amis" ),c("a" );
    a.affiche();
    c=b+a;
    c.affiche();
    return 0;
}
 
Mais si j'enlève c=a+b; sa marche.
si je remplace cette ligne par (a+b).affiche(); cela m'affiche bien "Salut l'amis". Et si je met c=a;c.affiche(); cela me met bien Salut

Reply

Marsh Posté le 02-02-2011 à 19:15:32    

Un Programmeur a écrit :

Tu ne peux pas passer un temporaire (ce que le resultat de a+b est) a une reference non const.


 
Comment résoudre ce problème? Car si je met const ou non a operator= cela ne change rien.

Reply

Marsh Posté le 02-02-2011 à 19:28:25    

mr simon a écrit :

ca depend ptet du compilateur (ce qui m'etonnerais), mais sur visual 2008:


 
Alors effectivement, cela ne marche pas sous gcc 4.1.2 ...  
 
Goku46, poste peut etre tout ton message d'erreur, peut etre que cela aidera ...
 
Edit: Alors effectivement visual autorise cela dans certaines version (il semblerait que les versions recentes empeche cela), mon visual m'affiche le warning C4239 si la reference n'est pas constante ... (Niveau 4)


Message édité par mr simon le 02-02-2011 à 19:47:57
Reply

Marsh Posté le 02-02-2011 à 20:44:39    

Voici maintenant le prototype de ma fonction
chaine & operator= (chaine const &T);
Pourquoi le compilateur n'aime pas que l'on ne mette pas le const??
 
Voici le message d'erreur :
error: no matching function for call to 'chaine::chaine(chaine)'
note: candidates are: chaine(chaine& )
note:                    :  chaine::chaine(char*)

Reply

Marsh Posté le 02-02-2011 à 20:44:39   

Reply

Marsh Posté le 02-02-2011 à 21:04:00    

Goku46 a écrit :

Voici maintenant le prototype de ma fonction
Voici le message d'erreur :
error: no matching function for call to 'chaine::chaine(chaine)'
note: candidates are: chaine(chaine& )
note:                    :  chaine::chaine(char*)


 
Le message d'erreur se plaint du constructeur, pas de l'operateur = ...  
 
Ton constructeur de recopie devrait avoir le prototype suivant:

Code :
  1. chaine(const chaine& )

Message cité 1 fois
Message édité par mr simon le 02-02-2011 à 21:04:39
Reply

Marsh Posté le 02-02-2011 à 22:39:37    

mr simon a écrit :


 
Le message d'erreur se plaint du constructeur, pas de l'operateur = ...  
 
Ton constructeur de recopie devrait avoir le prototype suivant:

Code :
  1. chaine(const chaine& )



 
 :D  sa marche!!!!!Merci beaucoup
Aprés plusieur petit test il faut comme prototype
        -chaine(chaine const &T); pour le constructeur de recopie
        -chaine & operator= (chaine const &T);
 
Si l'un des deux manque la compilation plante completement.
 
Pourrait tu m'expliquer pourquoi il faut les const dans ces deux prototype stp??


Message édité par Goku46 le 02-02-2011 à 22:46:11
Reply

Marsh Posté le 02-02-2011 à 22:49:44    

Un programmeur a indique pourquoi:

Un Programmeur a écrit :

Tu ne peux pas passer un temporaire (ce que le resultat de a+b est) a une reference non const.


 
A noter que:

Code :
  1. chaine(chaine T);
  2. chaine& operator=(chaine T);


devrait aussi marcher, mais les prototypes que tu mentionnes sont preferables (evite une copie d'objet inutile).

Reply

Marsh Posté le 02-02-2011 à 22:51:38    

Reply

Marsh Posté le 03-02-2011 à 08:50:26    

mr simon a écrit :


Code :
  1. chaine(chaine T);


devrait aussi marcher


 
J'ai du mal a voir comment passer par valeur au constructeur de copie.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 03-02-2011 à 14:03:16    


mr simon a écrit :


 
A noter que:

Code :
  1. chaine(chaine T);
  2. chaine& operator=(chaine T);


devrait aussi marcher, mais les prototypes que tu mentionnes sont preferables (evite une copie d'objet inutile).


 
Je confirme,un prototype chaine& operator=(chaine T); fonctionne.  
Si je comprend bien a+b est temporaire et lorsque j'utilise chaine& operator=(chaine &T); j'envoie a la fonction l'adresse de l'objet temporaire. Mais avant de rentrer dans la fonction celui-ci est détruit et sa plante car l'adresse ne correspond plus a rien.
Or si j'utilise chaine& operator=(chaine const &T),je recrée un objet dans ma fonction qui sera différent de mon objet temporaire mais aura les même valeur. Et donc du coup sa ne plante pas car cette objet const continuera d'exister dans ma fonction.


Message édité par Goku46 le 03-02-2011 à 14:03:44
Reply

Marsh Posté le 03-02-2011 à 14:49:33    

Un Programmeur a écrit :


 
J'ai du mal a voir comment passer par valeur au constructeur de copie.


 
Autant pour moi, ce n'est pas bon !

Reply

Sujets relatifs:

Leave a Replay

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