You first of all need to distinguish between the copy constructor and the clone pattern.
A copy constructor is a constructor that creates a copy of a class.
MyClass a;
MyClass copy(a); // calls the copy constructor
You (usually) don't need to implement it yourself, the compiler will create a so-called implicit copy constructor for you. If you however need to implement (e.g. because you write a class that manages a resource), please consider the rule of five (Rule-of-Three becomes Rule-of-Five with C++11?).
A copy constructor is not virtual (in fact, constructors are never virtual).
A typical use case for the clone pattern is this:
#include <memory>
class MyAbstractClass {
virtual void someFunction();
};
class MyHeir : public MyAbstractClass {
virtual void someFunction() override { /* TODO */ }
};
class MyHeir2 : public MyAbstractClass {
virtual void someFunction() override { /* TODO */ }
};
std::unique_ptr<MyAbstractClass> ptr1 = std::make_unique<MyHeir>();
std::unique_ptr<MyHeir> clone; // TODO: clone
There is no way for the compiler to know at compile time whether ptr1
contains an instance of MyHeir
or of MyHeir2
. That's why you need the clone pattern. You basically just implement a virtual function that copies the class (read: calls the copy constructor).
// in MyAbstractClass
virtual MyAbstractClass* clone() = 0;
// in MyHeir
virtual MyHeir * /* return type covariance */ clone() {
return new MyHeir(*this); // call to the (implicit) copy constructor
}
// in MyHeir2
virtual MyHeir2 * /* return type covariance */ clone() {
return new MyHeir2(*this);
}
Now you can do:
std::unique_ptr<MyHeir> clone = ptr1->clone();