N08 N08 - 2 years ago 58
C++ Question

Overloading the assignment operator of a generic handle class

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

Answer Source

new Base is implicitly converted to Handle via Handle(T *t) constructor, and then assigned to h.

Implicit conversion from h = new Base works like this:

h = Handle<Base>(new Base);

I updated your example with some prints to illustrate this point: demo.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download