-2

Let's say I have this base class for a data container:

class BaseClass{
public:
    int a;

    int getA();
    void setA(int newA);
}

And I have a derived class:

class DerivedClass : BaseClass{
public:
    int b;

    int getB();
    void setB(int newB);
}

Now I create two instances of the derived class:

DerivedClass* first = new DerivedClass();
DerivedClass* second = new DerivedClass();

Ok, here is my question: How can I let second point to a deep copy of firsts object (without producing a memory leak)?

Also, I have to consider that the class / function which handles both pointers and wants to copy them isn't aware of the exact inheritated class. So those pointers could also point to another inheritance of BaseClass, and the copy function has to work still and copy all! members.

Ben
  • 191
  • 9
  • Can you give a more complete example? This doesn't give us a lot of information on `derivedClass` or what it's derived from. – tadman Mar 16 '18 at 17:07
  • 7
    `derivedClass x = *new derivedClass();` memory leak... – llllllllll Mar 16 '18 at 17:07
  • There is no pointer slicing involved, there is convoluted usage of objects by value with memory leaks – Slava Mar 16 '18 at 17:09
  • 1
    What do you intend by `x= *new ...`? That asterisk... – Ripi2 Mar 16 '18 at 17:09
  • 2
    Typically solved with a `clone` method. Remember that different objects derived from the base will have different sizes and shapes. The best base can do is slice. – user4581301 Mar 16 '18 at 17:09
  • "Is there a way to fix this?" yes use virtual function(s) – Slava Mar 16 '18 at 17:10
  • `*b = *a` will call `baseClass::operator=(const baseClass&)`. At this point your code doesn't know that it's dealing with `derivedClasses`. – Kevin Mar 16 '18 at 17:11
  • derivedClass x = *new derivedClass(); Are you sure it will be compiled ? derivedClass *x = new derivedClass(); baseClass *a = x; - this will work; &x taking address of variable . Pointer is an integer e.g. unsigned long or unsigned long long e.g. size_t variable with the meaning - memory address. So &x result will be derivedClass * * – Victor Gubin Mar 16 '18 at 17:11
  • 2
    To elaborate on what @user4581301 said, suppose you have two different derived types, and `a` points to an object of one derived type and `b` points to an object of the other derived type. What should `*b = *a` do? – Pete Becker Mar 16 '18 at 17:11
  • 2
    @VictorGubin there is dereference there `derivedClass x = *new derivedClass();` as OP thinks that if he puts `new` somewhere it would work like pointers but there is no difference than `derivedClass x` rather than memory leak – Slava Mar 16 '18 at 17:13
  • 1
    Possible duplicate of [How to copy/create derived class instance from a pointer to a polymorphic base class?](https://stackoverflow.com/questions/5731217/how-to-copy-create-derived-class-instance-from-a-pointer-to-a-polymorphic-base-c) – user4581301 Mar 16 '18 at 17:15
  • 1
    Handy reading: [Why should C++ programmers minimize use of 'new'?](https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new). – user4581301 Mar 16 '18 at 17:19
  • @Slava I didn't meant x and y as pointers but a and b – Ben Mar 16 '18 at 17:27
  • And why does this lead to a memory leak? Shouldn't I use the dereference? – Ben Mar 16 '18 at 17:27
  • You should not use `new` there at all, or if you do need dynamically allocated object use smart pointers. Every call to `new` must be accompanied with `delete` – Slava Mar 16 '18 at 17:32
  • 2
    In `derivedClass x = *new derivedClass();`, `new derivedClass()` allocates space for a `derivedClass` in Dynamic storage (probably a heap), constructs a `derivedClass` in that space, and returns a pointer to it. This object is then copied into another `derivedClass` being constructed in Automatic storage (probably a stack). You keep the copy as `x`, but the pointer to dynamically allocated object is discarded, making it next to impossible to later `delete` to fee up the allocation. This is the leak. – user4581301 Mar 16 '18 at 17:51
  • You could get the effect you need without the leak with `derivedClass x;`. You might want, and been trying to get, something else, but you don't need it. – user4581301 Mar 16 '18 at 17:52

1 Answers1

2

This code:

derivedClass x = *new derivedClass();
derivedClass y = *new derivedClass();

is a convoluted way to say:

derivedClass x = derivedClass();
derivedClass y = derivedClass();

putting new there only creates a memory leak and does not make x or y any different and would not make them "pointers" as you think. As for this:

*b = *a;

to work properly you should use a virtual function instead:

class Derived {
public:
    virtual void copy_to( Base &b ) const override
    {
        if( Derived *d = dynamic_cast<Derived*>( &b ) ) 
            *d = *this;
    }

and call it like this:

 a->copy_to( *b );

Of course copy_to needs to be defined and implemented in the base and every derived class.

psmears
  • 21,582
  • 4
  • 37
  • 47
Slava
  • 40,641
  • 1
  • 38
  • 81