You're operator+() is seriously whacked. Consider the idea of "term" ownership. Each polynomial has a linked list of terms. It owns this list (at least it better). Now consider this brief analysis of your operator +():
Polynomial Polynomial::operator+(const Polynomial & poly) const 
{
    // hopefully creates a deep copy of *this
    Polynomial p2 = *this;
    // walk *our* terms (not the copy in p2??) to find the end.
    term * temp = (*this).ptr;
    while(temp->next != NULL)
        temp = temp->next;
    // once we find the end, we then *LINK* the params term-list
    //  which *they* are **supposed** to own, to our list. (and 
    //  p2 is still out there with a copy of our original content).
    temp->next = poly.ptr;
    // now we return p2, still holding a copy of our former self,
    // and we now have a cross-linked term list between us and the 
    // parameter poly
    return p2;
}
I sincerely hope it is evident what is wrong with that. For this to work correctly, your operator should be returning a by-val, (which it is, hooray!), and manufacture that thing correctly:
- Make a copy (lets call it p2) of *this (you have that)
- Find the end of the term list owned by p2
- Duplicate all terms in the rhsparameter ofoperator +(const Polynomial* rhs), linking the copies one-by-one to the tail ofp2's term list. Note: the tail will move with each new term linked.
- Return p2 by val. If your copy-ctors and destructors are doing their job, everything should come out fine. When done, both *this, and rhsshould be untouched.
Thats about the extent I can offer. Good luck.
PS: For extra-credit-bonus-round, sort your terms in your list as you insert them. This will get you one step closer to a like-degree merge, which will be the backbone of operator +=() and greatly assist your operator +(). The latter literally degenerates to Polynomial p2 = *this; p2 += poly; return p2;