Try using the 'one true copy constructor': the copy-swap idiom.
Writing a swap function for two polynomials is easy.
Writing the copy constructor is easier than writing operator= (because the destructor already deals with destroying the elements).
Your operator= then looks like:
anyType& operator=(const anyType& other) { anyType tmp = other; this->swap(tmp); return *this;}
The above code will be as exception safe as your swap (and swap shouldn't throw), copy constructor and destructor. It works for almost every class that uses pointer or value semantics on swap (reference semantics on swap breaks it).
You have to write copy construct and destructors anyhow. And swap is easy to write. So you have just reduced code duplication.
And in most cases, there is next to no overhead from the temporary object created by the copy constructor.
And yes, you really should be thinking about using a std::list or the like. Writing a list by hand, as more than a learning exercise, is a bad idea.
...
For the copy constructor, I'd write:
PolyPtr clonePolyPtr( PolyPtr src ) { if (!src) return src; PolyPtr tmp = new PolyPtr(); tmp->coefficient = src->coefficient; tmp->power = src->power; tmp->link = clonePolyPtr( src->link ); return tmp;}
(Note that making the above exception-safe is annoying. Which is another reason to use std::list.)
Now your copy constructor is '0' lines long:
Polynomial::Polynomial( const Polynomial& other ):head( clonePolyPtr(other.head) ) {}
Swap is easy:
void Polynomial::swap( Polynomial& other ) { std::swap( head, other.head );}
And .. done. Well you need to write Polynomial::~Polynomial, but you would have had to do that anyhow.
Going deeper down the rabbit hole, you could use boost::shared_ptr and make the cleanup code trivial (ie, a trivial destructor works).