Search code examples
c++inheritancedynamic-castdowncast

Copying shared variables between derived classes (shallow copy is enough)


So, I have a Base class, and two Derived classes, let's call them Deriv1 and Deriv2.

Let's say Base class has lots of (protected or public) variables, which of course then are also included in Deriv1 and Deriv2.

Now let's say I have an instance of Deriv1. The billions of variables from the Base class are filled with individual values. Now I want to create a Deriv2 instance, using these shared values.

Now my question: How to copy over the Base class part of Deriv1 to Deriv2 without writing an assigment operator where I'd have to manually list all of the billions of Base class variables (and update it everytime I change something in the Base class)? Is there some way, be it dirty or not, to do this?

My initial idea was:

Deriv1 drv1;

... // actions regarding drv1, like changing variables

Base tempbase = drv1; // slicing off the non-base parts of Deriv1
Deriv2 drv2 = *dynamic_cast<Deriv2*>(&tempbase); // downcast

This did not work. It did compile (I had to add a virtual dummy function to Base for it), but during runtime, it said "access violation", so I guess dynamic_cast returned a null pointer. I tried using a reference instead pointer in the dynamic_cast, which also didn't work.


Solution

  • You could make use of the (implicitly defined) copy constructor of the base class, which copies all members (even private ones) by value (i.e. shallow copy). You could define an explicit copy constructor for the base class as well, but it seems not to be necessary in your case. See the following example:

    class A  {
      public:
        A (int x, int y) : x(x), y(y) { };
        // implicitly defined: A (const A &anA) : x(anA.x), y(anA.y) {  }
      private:
        int x, y;
    };
    
    class B : public A {
      public:
        int z;
        B(const A&anA) : A(anA) { }
        B(const B&b, int z) : A(b), z(z) { }
    };
    
    class C : public A {
      public:
        int anythingElse;
        C(const A&anA) : A(anA) { }
    };
    
    
    int main()
    {
        A a(10,20);  // a.x = 10; a.y = 20
        B b1(a);     // b1.x = 10, b1.y = 20, b1.z = undefined.
        B b2(b1,30); // b2.x = 10, b2.y = 20, b2.z = 30.
        C c(b1);     // c.x = 10; c.y = 20; c.anythingElse = undefined
    
        return 0;
    }