PayOffDoubleDigital thePayOff(Low,Up); VanillaOption theOption(thePayOff,Expiry);
这里的问题是VanillaOption包含对thePayOff的引用.如果是这种情况并且某人修改了PayOff,则可能无意中修改了该选项的行为.他建议的解决方案是在PayOffDoubleDigital的基类PayOff中创建一个虚拟拷贝构造函数,以便该选项包含自己的副本:
virtual PayOff* clone() const = 0;
然后在每个继承的类中定义:
PayOff* PayOffCall::clone() const { return new PayOffCall(*this); }
在C 11中,返回new会让我感觉不合适.那么使用C 11处理这个问题的正确方法是什么?
解决方法
The solution he advises is to create a virtual copy constructor in PayOffDoubleDigital’s base class […]
首先,clone()不是复制构造函数.类X的复制构造函数是一个特殊的成员函数,没有返回类型,通常具有签名:
X(X const&)
并可能有签名:
X(X&)
函数clone()只是一个常规(虚拟)函数,它的特殊含义被你 – 用户 – 识别为创建对象克隆的东西,而不是编译器,它不知道clone()的作用.
Returning new caught me as something that might be inappropriate in C++11
这是真的,使用new在C 11中不是惯用的.事实上,在C 11中你应该(几乎)永远不会使用new,除非你正在进行真正的低级内存管理(除非你真的需要,你应该避免使用) – 并且C 14,你可以删除“差不多”.不幸的是,这可能是需要新功能的特殊情况.
我这样说是因为我相信返回一个unique_ptr听起来像是在这里做的适当的事情(选项对象必须保持自己的PayOff对象,并且只要选项对象是活着的,它必须保持活着),并且有C 11中没有std :: make_unique()函数(它将在C 14中出现):
std::unique_ptr<PayOff> PayOffCall::clone() const { return std::unique_ptr<PayOff>(new PayOffCall(*this)); }
让VanillaOption(或其基类)持有unique_ptr而不是原始指针会使得不必删除clone()返回的PayOff对象.反过来,不必删除该对象意味着无需定义用户提供的析构函数,也无需关注Rule of Three,Rule of Five或其他内容.
无论何时,请按照R. Martinho’s Fernandes’s advice进入Rule of Zero.