从下一篇文章中的评论
habr.com/en/post/460831/#comment_20416435以及在那里进行的讨论来看,关于如何正确地将参数传递给构造函数或setter的文章不会妨碍Habré。 StackOverflow有很多类似的资料,但是我不记得这里的内容。
因为该文章中的示例是完全正确的,并且该文章的作者是绝对正确的。 这是一个例子:
此类代码使您可以涵盖使用该类的所有(几乎所有)可能的选项:
std::string first{"abc"}, last{"def"}; person p1{first, last};
与旧方法比较,当由const&:传递时,肯定更糟,因为它不包括选项(3):
使用&&的替代方法也更糟,但方向相反:
如果您不害怕组合爆炸,可以给&&一个机会(但是为什么呢?速度没有真正的提高,优化器也不会停止工作):
或同一件事,仅使用模板(但又为什么?):
即使您没有std :: string,而是您自己编写的大型类的某个对象,并且希望人们移动它(而不是复制),那么在这种情况下,最好禁止构造函数从该大型类中进行复制,而不是将其传递给任何地方由&&。 这样更可靠,代码更短。
最后,关于如何做不到的几个选择:
所以不要:
为什么会这样,基本原理是什么? 这很简单:通常,对象应拥有其属性。
如果对象不想拥有某物,则它可以为此“物”拥有shared_ptr。 顺便说一句,在这种情况下,shared_ptrs也必须通过值传递,而不是通过常量链接传递-与本文开头的第一个示例没有区别:
请注意:std ::移动shared_ptr是完全合法的,它消除了将shared_ptr链接计数器锁定在内存中的开销(数百个CPU周期)及其增量。 它不会影响对象及其链接的寿命。 但是,当然,只有不再需要下面代码中的psh链接时,才可以执行(X)。
道德:一般不要使用const&。 根据情况看。
聚苯乙烯
传递构造函数参数时,请使用{}代替()。 时尚,现代,青春。
PPS
总之,还有一件事:std :: move()实际上不移动任何东西,它本身转换为零汇编程序指令。 std :: move()所做的全部工作就是在链接上放置一个特殊的“粘性标签”,将其转换为&&-rvalue引用。 此外,使用此标签,您可以单独“匹配”函数参数的类型(例如,对于&&-参数有单独的函数重载,对于&-parameter有单独的函数重载)。 &&-标签的含义是使调用代码能够告诉被调用者:“如果需要,您可以从此链接中获取值,我不再需要它; 但是只有当你吃饭时,才留下骨头,然后我仍然需要为剩下的骨骼调用析构函数。” 取得同样的成功,就有可能传输普通的&链接(您也可以使用它们“吃掉”一个对象),但是使用&&语义更好,因为 您不会混淆:您可以在哪里吃饭,哪里只能闻到气味。
在这方面,应该将名称std :: move()识别为极其不成功。 将其命名为std :: eat_me_if_you_want()或std :: bon_appetit()是正确的。 但是std :: move()较短。