[英]What's the advantage of using move constructor vs passing a pointer?
Foo(Foo&& other) {
this->bar = other.bar;
other.bar = nullptr;
}
Foo(Foo* other) {
this->bar = other->bar;
other->bar = nullptr;
}
上面两个似乎只是在做同样的事情。 那么为什么推荐使用移动构造函数呢? 它提供了哪些优势?
使用正确的移动构造函数的原因有很多:
习俗。 考虑以下代码:
Foo foo; Foo bar(std::move(foo));
如果您看到该代码,您将非常清楚您要做什么:您将foo
移到bar
。 相比之下:
Foo foo; Foo bar(&foo);
这是什么意思? 它是否存储指向另一个Foo
的指针? Foo
是某种链表节点类型吗? 您必须在Foo
的基于指针的构造函数的文档中查找它。
您无法获得指向纯右值的指针。 Foo bar(Foo{})
将(C++17 之前)创建一个临时纯右值,然后从它移入bar
(移动可以在 C++17 之前省略)。 但是你不能这样做: Foo bar(&Foo{})
。
您可以从有意义的事物中获得自动移动。 C++17 的广义省略使许多这些自动动作消失,但仍有一些:
Foo function() { Foo foo; //Do stuff return foo; }
这将从foo
移动而无需调用std::move
。 原因是foo
是一个即将被销毁的局部变量。 以这种方式返回它意味着从它移动到返回值是完全合理的。
您的方式需要明确地编写return &foo
。 这使得auto
返回类型推导变得相当困难。 这样的函数会推导出Foo*
,这意味着您刚刚返回了一个悬空指针。 而如果你确实return foo;
,它推导出一个Foo
纯右值,并自动移动(可能会被忽略)。
不需要nullptr
检查。 如果您使用Foo*
,则可能有人会传递空指针。 而使用参考,则不太可能(而且他们已经调用了 UB)。
如果我们想要对现有语言结构的移动支持,我们只需使用非const
引用来表示“移动”,而不是指针。 通过给它自己的语法,明确什么时候我们在移动什么东西,什么时候我们不移动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.