C++ Rvalue引用和移动语义

Met*_*est 11 c# c++ java c++11

C++ 03存在可能隐式发生的不必要副本的问题.为此,C++ 11引入rvalue referencesmove semantics.现在我的问题是,这个不必要的复制问题是否也存在于C#和java等语言中,还是只是一个C++问题?换句话说,rvalue references与C#或Java相比,C++ 11的效率是否更高?

就C#而言(允许运算符重载),假设我们有一个数学向量类,我们就像这样使用它.

vector_a = vector_b + vector_c;
Run Code Online (Sandbox Code Playgroud)

编译器肯定会转换vector_b + vector_c为一些临时对象(让我们调用它vector_tmp).

现在我不认为C#可以区分临时右值vector_tmp或者像左值这样的左值vector_b,因此我们必须将数据复制到vector_a任何地方,这在C++ 11中使用rvalue references和很容易避免move semantics.

Seb*_*ach 7

C#和Java中的类引用在shared_ptrC++中具有s的一些属性.但是,rvalue引用和移动语义更多地与临时值类型相关,但与C++值类型相比,C#中的值类型非常不灵活,而且从我自己的C#经验来看,你最终会得到类,而不是结构,大多数的时间.

所以我的假设是Java和C#都不会从那些新的C++特性中获得太多利益,这使得代码能够安全地假设某些东西是否是临时的,而不是复制让它只是窃取内容.


sho*_*fee 5

是的,C#和java中有不必要的复制操作.

与C#或Java相比,右值引用能否使C++ 11更高效?

答案是肯定的.:)

  • 你什么时候认为它发生在Java?请举个例子.它可以在调用克隆等的特定实现中发生,但这似乎是不重要的.Java没有默认的复制构造函数和隐式副本,因为它默认传递对象的引用(实际上是按值). (3认同)
  • 好.几乎.我是说,由于Java不使用复制构造函数通过自动对象复制传递值,而是通过值传递值,因为它不会发生在对象的引用中.如果java在传递对象时自动调用深度clone(),那将是同样的问题.部分问题可能发生在Java的特定实现中,例如,如果你使用不可变方法模拟运算符重载,例如a = a.add(b.add(c)),如果add创建了一个新对象,但是没有这样的默认行为在Java中. (3认同)