Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

understanding virtual copy constructors

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.

like image 747
EindacorDS Avatar asked Dec 27 '22 09:12

EindacorDS


1 Answers

The misunderstanding is here:

*this means its passing the address of whatever object is being cloned

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 type Derived &, 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 what new does), the new space is initialised by the copy constructor Derived(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: If C is a class, then

new C;

allocates enough space for an object of type C and then calls the constructor of C to initialise that space. This is part of the semantics of new: It always calls the constructor to initialise the newly allocated space.

When you call

new C(a,b,c);

with some arguments a, b and c, then new will call a constructor of C 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

new C(a);

with an argument a that is itself of type C&, new will, as always, call the appropriate constructor. The appropriate constructor is either C(C &) (if defined), or C(const C&) (copy-constructor auto-defined by the compiler).

like image 55
jogojapan Avatar answered Jan 09 '23 01:01

jogojapan