Copy a derived class with only a base class pointer in C++

Viewed 73

I'm trying to make a copy of a derived class with only a base class pointer.

So if I have:

class BaseClass; //Abstract class with =0 functions
class LeftClass : BaseClass;
class RightClass : BaseClass;

And I have a function that takes a BaseClass as a parameter:

void Function(BaseClass* baseClass)

I want to make a copy of BaseClass, but I want to also copy the extended functionality of LeftClass OR RightClass, but I don't know which one was passed to the function - both are possible.

So I have something like this:

//global
vector<BaseClass*> myVector;

void Function(BaseClass* baseClass)
{
   BaseClass* baseClassCopy = new BaseClass(baseClass);
   myVector.push_back(baseClassCopy);
}   

And then I call the function with a left or right class

int main()
{
   LeftClass leftClass;
   Function(&leftClass);
   LeftClass* ResultOfCopy = myVector.at(0);
}

That code doesn't copy over the entire leftclass as a copy, is there a way to do this I'm overlooking?

Also BaseClass is abstract, some of the functions are =0 so I can't new one up. Otherwise there is a copy function in the other classes to use.

2 Answers

If you can't change any of the classes to add a clone function then you can manually do that yourself by using dynamic_cast to determine its run time type and call the correct derived constructor. That would look like

void Function(BaseClass* baseClass)
{
    if (auto ptr = dynamic_cast<LeftClass*>(baseClass))
        myVector.push_back(new LeftClass(*ptr));
    if (auto ptr = dynamic_cast<RightClass*>(baseClass))
        myVector.push_back(new RightClass(*ptr)); 
}  

and you can see it working in this live example

This kind of problem is usually solved by a clone() method.

class BaseClass
{
    virtual BaseClass* clone()            = 0
};

class LeftClass: public BaseClass
{
    virtual LeftClass* clone() override {return new LeftClass(*this);}
};
class RightClass: public BaseClass
{
    virtual RightClass* clone() override {return new RightClass(*this);}
};
class RightRightClass: public RightClass
{
    virtual RightRightClass* clone() override {return new RightRightClass(*this);}
};

Your function is now easy to write:

void Function(BaseClass* baseClass)
{
   BaseClass* baseClassCopy = !baseClass ? nullptr : baseClass->clone();
   myVector.push_back(baseClassCopy);
}   
Related