C ++ 11虚拟副本构造函数 [英] C++11 virtual copy constructor

查看:62
本文介绍了C ++ 11虚拟副本构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读Mark Joshi的C ++设计模式和衍生产品定价,并在C ++ 11中实现他的代码.一切进展都很好,直到我谈到了第4章,他在这里讨论了虚拟副本构造函数.

I'm reading C++ Design Patterns and Derivatives Pricing by Mark Joshi and implementing his code in C++11. Everything has gone pretty well until I hit chapter 4 where he discusses virtual copy constructors.

PayOffDoubleDigital thePayOff(Low, Up);
VanillaOption theOption(thePayOff, Expiry);

这里的问题是 VanillaOption 包含对 thePayOff 的引用.如果是这种情况,并且有人修改了 thePayOff ,则可以不经意地修改 theOption 的行为.他建议的解决方案是在 PayOffDoubleDigital 的基类 PayOff 中创建一个虚拟副本构造函数,以便 theOption 包含其自己的副本:

The problem here is that VanillaOption contains a reference to thePayOff. If that's the case and someone modifies thePayOff, the the behavior of theOption could be modified unwittingly. The solution he advises is to create a virtual copy constructor in PayOffDoubleDigital's base class, PayOff so that theOption contains its own copy:

virtual PayOff* clone() const = 0;

,然后在每个继承的类中定义:

and then defined in each inherited class:

PayOff* PayOffCall::clone() const
{
    return new PayOffCall(*this);
}

返回新的东西使我陷入了C ++ 11中可能不合适的事情.那么使用C ++ 11处理此问题的正确方法是什么?

Returning new caught me as something that might be inappropriate in C++11. So what is the proper way of handling this using C++11?

推荐答案

他建议的解决方案是在PayOffDoubleDigital的基类[...]中创建一个虚拟副本构造函数.

The solution he advises is to create a virtual copy constructor in PayOffDoubleDigital's base class [...]

首先, clone()不是复制构造函数.类 X 的副本构造函数是一个特殊的成员函数,没有返回类型,通常具有以下签名:

First of all, clone() is not a copy-constructor. A copy constructor for class X is a special member function with no return type which usually has the signature:

X(X const&)

并且可能具有签名:

X(X&)

Function clone()只是一个常规(虚拟)函数,您(用户)将其特殊含义识别为创建对象克隆的某种东西,但编译器却不知道,不知道 clone()会做什么.

Function clone() is just a regular (virtual) function, and its particular meaning is recognized by you - the user - as something which creates clones of your object, but not by the compiler, which has no idea what clone() does.

重新使用新内容使我陷入了C ++ 11可能不合适的事情

Returning new caught me as something that might be inappropriate in C++11

是的,在C ++ 11中使用 new 并不是习惯用法.实际上,在C ++ 11中,除非真正执行低级内存管理,否则(几乎)永远不要使用 new (除非您真的需要,否则应避免使用此方法))-在C ++ 14中,您可以删除几乎".不幸的是,这可能是需要 new 的特殊情况.

That's true, using new is not idiomatic in C++11. In fact, in C++11 you should (almost) never use new unless you are doing really low-level memory management (something you should avoid unless you really have to) - and in C++14, you can remove the "almost". Unfortunately, this is likely the exceptional case where new is needed.

之所以这样说,是因为我相信返回 unique_ptr 听起来像是在这里要做的适当的事情(选项对象必须拥有自己的 PayOff 对象,并且只要选项对象处于活动状态就必须保持活动状态),并且C ++ 11中没有 std :: make_unique()函数(在C ++ 14中将存在该功能):

I'm saying this because I believe returning a unique_ptr sounds like the appropriate thing to do here (the option object has to hold its own PayOff object, and that must stay alive just as long as the option object is alive), and there is no std::make_unique() function in C++11 (it will be there in C++14):

std::unique_ptr<PayOff> PayOffCall::clone() const
{
    return std::unique_ptr<PayOff>(new PayOffCall(*this));
}

具有 VanillaOption (或其基类)保存 unique_ptr 而不是原始指针将使得不必删除 clone()返回的PayOff 对象.反过来,不必删除该对象意味着无需定义用户提供的析构函数,也无需注意 五法则 ,或者什么都没有.

Having VanillaOption (or its base class) hold a unique_ptr rather than a raw pointer would make it unnecessary to delete the PayOff object returned by clone(). In turn, not having to delete that object means no need to define a user-provided destructor, and no need to take care about the Rule of Three, Rule of Five, or whatnot.

只要可以,请遵循R.马丁尼奥(Martinho)的费尔南德斯(Fernandes)的建议,并选择 零规则 .

Whenever you can, follow R. Martinho's Fernandes's advice and go for the Rule of Zero.

这篇关于C ++ 11虚拟副本构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆