I'm having trouble understanding what's really happening with the code in a book I'm using to learn C++. Here's the code:
class Base
{
public:
Base() {};
virtual ~Base() {};
virtual Base* Clone() {return new Base(*this);}
};
class Derived
{
public:
Derived() {};
virtual ~Derived() {};
virtual Base* Clone() {return new Derived(*this);}
};
So in this Clone()
function I understand that the function returns a pointer to a Base class object. What I don't understand is what's happening within that function. When I've previously used new
as in int *pInt = new int
, I was under the impression that new
essentially allocates enough memory on the free store for an integer, then returns that address, applying the address to the pointer pInt
. With that same logic I'm trying to understand the new Derived(*this)
portion of the code. So, I think it is allocating enough memory on the free store for a Derived class object, and returning the address, which is then returned by the function Clone()
.
Why, though, does it pass *this
through the constructor, if that is a constructor? I understand *this
means its passing the address of whatever object is being cloned, but I don't understand the syntax of class_name(address_of_an_object)
in the context of the new
function.
Could someone please explain what's happening in that portion?
Thanks in advance.
The misunderstanding is here:
In reality,
this
is the address of the object that is being cloned, but*this
(note the asterisk) is the result of dereferencing that address. So*this
is of typeDerived &
, it's a reference to the object being cloned, not its address.Therefore, calling
new Derived(*this)
means that after dynamically allocating space (which is whatnew
does), the new space is initialised by the copy constructorDerived(const Derived &)
, which in this case hasn't actually been user-defined, so the (compiler-generated) default version of the copy constructor is used.To clarify the semantics of
new
: IfC
is a class, thenallocates enough space for an object of type
C
and then calls the constructor ofC
to initialise that space. This is part of the semantics ofnew
: It always calls the constructor to initialise the newly allocated space.When you call
with some arguments
a
,b
andc
, thennew
will call a constructor ofC
that takes these three arguments. If no such constructor has been defined, you'll get a compiler error.Now in the special case where you call
with an argument
a
that is itself of typeC&
,new
will, as always, call the appropriate constructor. The appropriate constructor is eitherC(C &)
(if defined), orC(const C&)
(copy-constructor auto-defined by the compiler).