The rule of 3:
http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)
Constructors, Destructors and Copy Constructors tend to come in triplets.
If you define one, think long and hard why you haven't defined or disabled the others.
However, if you use reference-counting RAII pointers, you can go back to just defining constructors. And if your constructors merely exist to store non-pointer data, you similarly tend to have less issues.
Could I lead you down the rabbit hole?
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
Then change LLElement as follows:
boost::shared_ptr<LLElement> next; boost::weak_ptr<LLElement> previous;
And LinkedList as follows:
boost::shared_ptr<LLElement> first; boost::shared_ptr<LLElement> last;
And then make your code work. ;)
weak_ptrs can be created from shared_ptrs. You can get a shared_ptr from a weak_ptr by calling .lock() on the weak_ptr. weak_ptrs fail to produce a shared_ptr if the underlying data was destroyed before you call lock(). shared_ptrs are a reference-counting pointer (which is a weaker form of garbage collection, but also a much much cheaper one, than Java-style garbage collection).
The exercise might be fun to do. Include "printf-style" debugging to make sure that you aren't leaking a loop anywhere, and write & test a few methods like 'delete', 'insert', 'clone' and 'splice'. It would be a good exercise.