Joan Carles
Joan Carles

Reputation: 303

Cloning C++ class with pure virtual methods

I have the following relation of classes. I want to clone the class Derived, but I get the error "cannot instantiate abstract class". How I can clone the derived class? Thanks.

class Base {
public:
    virtual ~Base() {}
    virtual Base* clone() const = 0;
};

class Derived: public Base {
public:
    virtual void func() = 0;
    virtual Derived* clone() const {
        return new Derived(*this);
    }
};

Upvotes: 6

Views: 5961

Answers (4)

Martol1ni
Martol1ni

Reputation: 4702

You can not instantiate a class which has a pure virtual function like this:

virtual void yourFunction() = 0

Make a subclass or remove it.

Upvotes: 4

bartgol
bartgol

Reputation: 1873

I might be saying something stupid here, but I think that the clone method in the derived class should still return a pointer to the base class. Maybe it still compiles fine, but as far as maintainability of the code is concerned, I think is better to use the method clone only to return pointers to the base class. After all, if your derived class has to clone into a pointer to a derived class, you could as well just do

Derived original;
Derived* copy = new Derived(original)

Of course, you need to implement the copy constructor, but that should usually be implemented anyway (except for extreme cases).

Upvotes: 0

Sergey K.
Sergey K.

Reputation: 25386

Only concrete classes can be instantiated. You have to redesign the interface of Derived in order to do cloning. At first, remove virtual void func() = 0; Then you will be able to write this code:

class Base {
public:
    virtual ~Base() {}
    virtual Base* clone() const = 0;
};

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

Another solution is keeping pure virtual function in-place and adding a concrete class:

class Base {
public:
    virtual ~Base() {}
    virtual Base* clone() const = 0;
};

class Derived: public Base {
public:
    virtual void func() = 0;
};

class Derived2: public Derived {
public:
    virtual void func() {};
    virtual Derived2* clone() const {
        return new Derived2(*this);
    }
};

Upvotes: 7

VGE
VGE

Reputation: 4191

Only concrete class can be instancied. Func should be not pure.

Upvotes: 2

Related Questions