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]
....