C++ 11引入了一个新的rvalue引用概念.我正在某处读它,发现如下:
class Base
{
public:
Base() //Default Ctor
Base(int t) //Parameterized Ctor
Base(const Base& b) //Copy Ctor
Base(Base&& b) //Move Ctor
};
void foo(Base b) //Function 1
{}
void foo(Base& b) //Function 2
{}
int main()
{
Base b(10);
foo(b); -- Line 1 (i know of ambiquity but lets ignore for understanding purpose)
foo(Base()); -- Line 2
foo(2) ; -- Line 3
}
Run Code Online (Sandbox Code Playgroud)
现在我的理解有限,我的观察结果如下:
第1行将简单地调用复制构造函数,因为参数是左值.
在C++ 11之前的第2行会调用复制构造函数和所有那些临时复制内容,但是定义了移动构造函数,这里将调用它.
第3行将再次调用move构造函数,因为2将隐式转换为Base类型(rvalue).
请纠正并解释上述任何观察结果是否错误.
现在,这是我的问题:
我知道一旦我们移动一个物体,它的数据就会在呼叫位置丢失.所以,我在上面的例子中如何更改第2行以在foo中移动对象"b"(是否使用std :: move(b)?).
我读过移动构造函数比复制构造函数更有效.怎么样?我只能想到在移动构造函数的情况下我们在堆上有内存的情况不需要再分配.当我们在堆上没有任何内存时,这个陈述是否成立?
它是否比通过引用传递更有效(不,对吧?)?
小智 8
首先是你的"理解":
正如我所看到的,它们原则上是对的,但你应该知道Copy elision,这可能会阻止程序调用任何复制/移动构造函数.取决于您的编译器(-settings).
关于你的问题:
是的,你必须调用foo(std :: move(b))来调用一个带有左值的右值的函数.std :: move将进行演员表演.注意:std :: move本身不会移动任何东西.
使用move-constructor"可能"更有效率.实际上,它只允许程序员实现一些更高效的构造函数.示例考虑一个向量,它是一个类,指向一个保存数据的数组的指针(类似于std :: vector),如果你复制它就必须复制数据,如果移动它就可以传递指针并设置旧的一个到nullptr.但正如我在Scott Meyers 阅读的有效现代C++中所读到的:不要认为你的程序会更快,因为你使用std :: move everywere.
这取决于输入的用法.如果你不需要函数中的副本,在大多数情况下,通过(const)引用传递对象会更有效.如果您需要副本,有几种方法可以执行此操作,例如复制和交换习惯用法.但作为一个
| 归档时间: |
|
| 查看次数: |
1782 次 |
| 最近记录: |