Duplicating subclass of abstract baseclass

556 views Asked by At

I have an abstract base-class to enforce some subclasses to overload the << operator.

I am storing a bunch of pointers to instances of these subclasses in an std::stack... At some point I wish to duplicate the top item of the stack (and push it on top).

The problem is, I cannot instantiate an abstract class. And obviously since I want to do this for each of my subclasses, I won't know the type...

I wonder if this is even possible without adding another pure virtual method (say 'Base *clone() = 0') and implement it in each of my subclasses? Surely there must be a cleaner way.

2

There are 2 answers

0
Mark B On BEST ANSWER

I think you actually need a Clone method in this case. You want to dynamically copy the subclass item at runtime, and the normal way to change behavior at runtime is virtual methods. Without using some virtual method you would have no way of figuring out which child it is. You could probably use CRTP to automatically generate that Clone for you though:

// Totally uncompiled and untested.
class Base
{
public:
    virtual Base* Clone() const = 0;
};

template <class T>
class Child : public Base
{
public:
    virtual Base* Clone() const { return new T(*static_cast<T*>(this)); }
protected:
    Child(); // Can't instantiate directly
    Child(const Child& right); // Can't instantiate directly
};

class Grandchild : public Child<Grandchild>
{
    // Clone should do the right thing.
};
0
DeveloperChris On

Do you mean making a copy of the class, rather than duplicating the pointer.

You will need to either implement your own typing. in other words have a virtual function that returns the class type and then create the appropriate class

Or enable RTTI (Run-Time Type Information) to do the same thing. because RTTI effects every class its possibly more efficient to create your own typeof method.

Then you can

  1. Pop the pointer
  2. Get the type
  3. Instantiate the correct class using a copy constructor probably in a switch
  4. Push both back onto the stack

psuedocode

 base* ptr = stack.pop()
 base *copy
 switch (ptr->typeof()) {
  case class1type : copy = new class1(ptr) break;
  case class2type : copy = new class2(ptr) break;
  ...
}

stack.push (ptr)
stack.push(copy)

DC