The solution that he advises is to create a virtual copy constructor in the PayOffDoubleDigital base class [...]
First of all, clone() not a copy constructor. The copy constructor for class X is a special member function without a return type, which usually has a signature:
X(X const&)
And may have a signature:
X(X&)
The clone() function is just a regular (virtual) function, and its specific value is recognized by you - the user - as something that creates clones of your object, but not by a compiler that has no idea what clone() does.
The return of new caught me as something that might not be appropriate in C ++ 11
It is true that using new not idiomatic in C ++ 11. In fact, in C ++ 11 you should (almost) never use new unless you are performing really low-level memory management (which you should avoid if you really not necessary) - and in C ++ 14 you can delete "almost". Unfortunately, this is probably an exceptional case when new is required.
I say this because I think that returning unique_ptr sounds like a suitable thing here (the option object must contain its own PayOff object, and it must remain alive as long as the option object is alive), and in C ++ 11 there is no function std::make_unique() (it will be there in C ++ 14):
std::unique_ptr<PayOff> PayOffCall::clone() const { return std::unique_ptr<PayOff>(new PayOffCall(*this)); }
Having VanillaOption (or its base class), hold unique_ptr , not a raw pointer, would be unnecessary for the delete of the PayOff object returned by clone() . In turn, without delete this object, there is no need to determine the destructor provided by the user and there is no need to take care of Rule of Three , Rule of Five or something else.
Whenever you can, follow R. Martinho Fernandes and go to the Rule of Zero .