I have the following piece of code (from Koening & Moo Accelerated C++ page 255) that defines a generic handle class Handle. Handle is used to manage the memory of objects. However, there is an aspect of the code I don't quite follow. 
template <class T>
class Handle
{
  public:
    Handle() : p(0) {}
    Handle &operator=(const Handle &);
    ~Handle() { delete p; }
    Handle(T *t) : p(t) {}
  private:
    T *p;
};
template <class T>
Handle<T> &Handle<T>::operator=(const Handle &rhs)
{
    if (&rhs != this)
    {
        delete p;
        p = rhs.p ? rhs.p->clone() : 0;
    }
    return *this;
};
class Base
{
    friend class Handle<Base>;
  protected:
    virtual Base *clone() const { return new Base; }
  private:
    int a;
};
main()
{
    Handle<Base> h;
    h = new Base;
    return 0;
}
When we overload = why is the argument rhs of type const Handle (Handle<T> &Handle<T>::operator=(const Handle &rhs)) when the right-hand side in the assignment in main is of type Base* (h = new Base)? Shouldn't the argument rather be (const T &rhs) to accomodate the type that we assign to h? 
If I replace const Handle &rhs by const T &rhs then the program compiles - but I get a long list of errors starting with 
*** Error in `./main': double free or corruption (fasttop): 0x000055aca1402c20 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x790cb)[0x7f16c54020cb]
....
 
    