user1372984
user1372984

Reputation:

Why was my list altered after last function call?

I have a class Polynomial defined as

   template<typename, T>
   class Polynomial{
      Monomial<T> *head;
   public:
      Polynomial(Monomial<T> *p=NULL){ head=p;}
      Polynomial insert(T c, int n){
        Monomial<T>*q=new Monomial<T>(c,n);
        Monomial<T> *p=head, *t=NULL;
        while(p!=NULL && q->pw < p->pw) { t=p; p=p->next;}
        if(t==NULL){q->next=head; head=q; }
        else{ t->next = q;  q->next=p; }   
        return *this;
      }
      T evaluate(T x){
        T sum=0;
        for(Monomial<T>* p=head; p!=NULL; p=p->next)
            sum+=p->evaluate(x);
        return sum;
      }
   };

where Monomial is a linked list using struct. In my main function I have

    10    int main(){
    20        Polynomial<int> p;
    30        cout<<p.insert(1,2).insert(2,3).insert(2,1).insert(4,5).evaluate(2);
    40        p.destroy();
    50    }

I have break points at line 30 and 40 and at line 40 while debugging I realized that although my output was correct, the list I have in p wasn't the one I expected, it was like only the first insert(1,2) was called. So I put breakpoints in the insert and evaluate members and I observed that all the inserts were done before evaluate was called and after that my list returned to its state after the first insertion insert(1,2).

I really don't understand why this happened because after separating the insert calls like this

     30     p.insert(1,2);    p.insert(2,3);    p.insert(2,1);    p.insert(4,5);
     40     cout<<p.evaluate(2);

I got what I wanted but what is the difference between these two methods and why is the first one not giving me what I wanted (that is all insertion were present).

Upvotes: 0

Views: 73

Answers (3)

TieDad
TieDad

Reputation: 9939

It is because the insert returns Polynomial. Try to return a reference:

Polynomial &insert(T c, int n){

With returning Polynomial, insert always return a copy of the object itself. So line 30 makes many copies of the original p, but p is unchanged.

Upvotes: 2

Detheroc
Detheroc

Reputation: 1921

You need to change the return value of the insert method to a reference:

Polynomial & insert(T c, int n);

What you have now creates a copy of the object when returning from this function and the subsequent calls insert values into the copy.

Upvotes: 2

bash.d
bash.d

Reputation: 13217

In

 Polynomial insert(T c, int n){ // <- returns the value which cannot be chained
    Monomial<T>*q=new Monomial<T>(c,n);
    Monomial<T> *p=head, *t=NULL;
    while(p!=NULL && q->pw < p->pw) { t=p; p=p->next;}
    if(t==NULL){q->next=head; head=q; }
    else{ t->next = q;  q->next=p; }   
    return *this;
  }

you are returning *this -> okay, but if you want to use it as chained, you must return a reference like

  Polynomial& insert(T c, int n){ // <- see the Polynomial&, returns reference, which can be chained
    Monomial<T>*q=new Monomial<T>(c,n);
    Monomial<T> *p=head, *t=NULL;
    while(p!=NULL && q->pw < p->pw) { t=p; p=p->next;}
    if(t==NULL){q->next=head; head=q; }
    else{ t->next = q;  q->next=p; }   
    return *this;
  }

Upvotes: 4

Related Questions