为什么用户定义的移动构造函数禁用隐含拷贝构造函数? [英] Why user-defined move-constructor disables the implicit copy-constructor?

查看:486
本文介绍了为什么用户定义的移动构造函数禁用隐含拷贝构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然我读升压/ shared_ptr.hpp,我看到这个code:

While I'm reading boost/shared_ptr.hpp, i saw this code:

//  generated copy constructor, destructor are fine...

#if defined( BOOST_HAS_RVALUE_REFS )

// ... except in C++0x, move disables the implicit copy

shared_ptr( shared_ptr const & r ): px( r.px ), pn( r.pn ) // never throws
{
}

#endif

什么是评论生成的拷贝构造函数,析构函数除了在C ++ 11,移动禁用隐式副本精是什么意思吗?我们将永远写拷贝构造函数自己,prevent在C ++ 11这种情况呢?

What does the comment "generated copy constructor, destructor are fine except in C++11, move disables the implicit copy" mean here? Shall we always write the copy ctor ourselves to prevent this situation in C++11?

推荐答案

我upvoted ildjarn的答案,因为我发现它既准确又幽默。 : - )

I've upvoted ildjarn's answer because I found it both accurate and humorous. :-)

我提供一个备用的答案,因为我假设,因为这个问题的标题是,OP可能想知道的为什么的标准是这么说的。

I'm providing an alternate answer because I'm assuming because of the title of the question that the OP might want to know why the standard says so.

背景

C ++含蓄生成的拷贝成员,因为如果它没有,它会被仍然诞生于1985年已经因为它的所以与C和不兼容在这种情况下,我们不会今天讨论这个,因为C ++就不会存在。

C++ has implicitly generated copy members because if it didn't, it would've been still-born in 1985 because it was so incompatible with C. And in that case we wouldn't be having this conversation today because C++ wouldn't exist.

话虽这么说,隐式生成副本成员是类似于一个魔鬼交易。 C ++已经不能生下来就没有他们。但他们在他们默默实例的数量显著生成不正确的code邪恶。在C ++委员会不傻,他们知道这一点。

That being said, implicitly generated copy members are akin to a "deal with the devil". C++ couldn't have been born without them. But they are evil in that they silently generate incorrect code in a significant number of instances. The C++ committee isn't stupid, they know this.

C ++ 11

现在++已经诞生,并已演变成一个成功的大人是C,委员会将只是爱说:我们没有做隐式生成副本的成员了。他们是太危险了。如果你想要一个隐式生成副本会员,您可以选择加入该决定(而不是选择退出的话)。不过考虑到现有的C ++ code,如果这样做的目的是将破坏量,这无异于自杀。有一个的巨大的向后兼容性担忧是很有道理的。

Now that C++ has been born, and has evolved into a successful grownup, the committee would just love to say: we're not doing implicitly generated copy members any more. They are too dangerous. If you want an implicitly generated copy member you have to opt-in to that decision (as opposed to opt-out of it). However considering the amount of existing C++ code that would break if this was done, that would be tantamount to suicide. There is a huge backwards compatibility concern that is quite justified.

因此​​,委员会达成妥协的位置:如果你声明的举动成员(其中传统的C ++ code不能做的),那么我们将假设默认复印成员,很可能做错事。选择加入(与 =默认)如果你想他们。或者自己写他们。否则,它们被隐式删除。我们的最新经验与唯才是举类型的世界表明,此默认位置其实是相当普遍所期望的那样(如的unique_ptr 的ofstream 未来等)。并选入的费用实际上是相当小的 =默认

So the committee reached a compromise position: If you declare move members (which legacy C++ code can't do), then we're going to assume that the default copy members are likely to do the wrong thing. Opt-in (with =default) if you want them. Or write them yourself. Otherwise they are implicitly deleted. Our experience to-date in a world with move-only types indicates that this default position is actually quite commonly what is desired (e.g. unique_ptr, ofstream, future, etc.). And the expense of opting-in is actually quite small with = default.

展望

该委员会很想甚至说:如果你写一个析构函数,它很可能是隐式副本的成员是不正确的,所以我们将其删除。这是C ++ 98/03三法则。然而,即使这会破坏很多code的。然而,委员会已表示,在C ++ 11,如果你提供了一个用户声明的析构函数,复制成员的隐代是德precated 。这意味着,该功能可以在一个未来的标准被移除。而且现在任何一天你的编译器可能开始在这种情况下发放德precated警告(标准不能指定警告)。

The committee would love to even say: If you've written a destructor, it is likely that the implicit copy members are incorrect, so we will delete them. This is the C++98/03 "rule of three". However even that would break lots of code. However the committee has said in C++11 that if you provide a user-declared destructor, the implicit generation of copy members is deprecated. That means that this feature could be removed in a future standard. And that any day now your compiler might start issuing "deprecated warnings" in this situation (the standard can not specify warnings).

结论

所以事先警告:C ++已经长大了,成熟了过去的几十年。这意味着,你父亲的C ++可能需要迁移到处理您的孩子的C ++。这是一个缓慢的,渐进的过程,让你不扔你的手,只是移植到另一种语言。但它的的变化,即使缓慢的。

So be forewarned: C++ has grown up and matured over the decades. And that means that your father's C++ may need migrating to deal with your child's C++. It is a slow, gradual process so that you don't throw up your hands and just port to another language. But it is change, even if slow.

这篇关于为什么用户定义的移动构造函数禁用隐含拷贝构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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