2

I'm trying to get the hang of Inheritance and Deep Copy but I'm having some trouble. I have 3 classes (1 Base and 2 Derived) as follows :

class Base {
protected:
    int id;
public:
    Base(int i) : id(i) {};
    virtual ~Base();
};

class DeriveA : public Base {
    int specialID;
public:
    DeriveA(int s, int i) : Base(i), specialID(s) {};
    ~DeriveA();
};

class DeriveB : public Base {
    int specialID;
public:
    DeriveB(int s, int i) : Base(i), specialID(s) {};
    ~DeriveB();
};

On my main I have something like this:

int main() {

    Base **Array;
    int i, n;
    Array = new Base*[5];
    for (i = 0 ; i < 5 ; i++) {
        n = rand() % 2;
        if (n)
            Array[i] = new DeriveA(i, n);
        else
            Array[i] = new DeriveB(i, n);
    }
}

If specific circumstances are met I want to hard copy an array object over other objects. I find it hard to make a copy constructor for it since Array[0] = Array[2]; doesn't work for me. I don't want to use any vectors or std::copy because that's not my "educational" goal.

PS 1 : Is assignment operator better for this purpose since I have initialized all objects of array.

PS 2 : Since it's a generic code there are some errors that I left out. Please ignore them and focus on the question.

LogicStuff
  • 19,397
  • 6
  • 54
  • 74
Alex R.
  • 459
  • 5
  • 16
  • I believe a more generic code is more helpful from the perspective that it is easier to understand and has easier application to more specific code. – Alex R. Jan 04 '16 at 15:53
  • `Array[0] = Array[2];` should compile, with a potential memory leak. – LogicStuff Jan 04 '16 at 15:54
  • Well it does compile with a seg fault at the destructions.However when I change Array[2] private members the same applications are copied to Array[0].Drawback of swallow copy I guess – Alex R. Jan 04 '16 at 16:03
  • You didn't actually show us how you're doing it. – LogicStuff Jan 04 '16 at 16:04

2 Answers2

3

First of all, you should have allocated array of Base*:

Array = new Base*[5];

And this is how you initialize the element pointers:

Array[i] = new DeriveA(i,n);

not like this:

// * added for further clarification, otherwise invalid and rejected at compilation
*Array[i] = DeriveA(i,n);

because that is:

  1. dereferencing uninitialized pointer (undefined behavior)
  2. object slicing

Note that your Base is missing a virtual destructor.

And then of course deallocation... You can find out how to do it here.

Community
  • 1
  • 1
LogicStuff
  • 19,397
  • 6
  • 54
  • 74
2

If you want to clone the objects, rather than copy pointers to the same object, you can use a virtual cloning function:

class Base {
public:
    virtual Base* clone() const = 0;
    virtual ~Base();  // Don't forget 'virtual' here
};

class DeriveA : public Base {
public:
    virtual Base* clone() const { return new DeriveA(*this); }
};

class DeriveB : public Base {
public:
    virtual Base* clone() const { return new DeriveB(*this); }
};


// ...

Array[0] = Array[2]->clone();
molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • I guess I was trying to find solution at the wrong places. Because on my actual code Base is an abstract class and I get an Error in this line virtual Base* clone() const { return new Base(*this); } obviously. The code is working if I remove the pure virtual functions but is there any way to manipulate this line and keep the pure virtual functions? – Alex R. Jan 04 '16 at 16:18
  • 1
    @AlexF. Make the cloning function abstract as well (see edit). – molbdnilo Jan 04 '16 at 16:41